diff --git a/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md b/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md deleted file mode 100644 index 94a84906f24..00000000000 --- a/.github/ISSUE_TEMPLATE/lgtm-com---false-positive.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: LGTM.com - false positive -about: Tell us about an alert that shouldn't be reported -title: LGTM.com - false positive -labels: false-positive -assignees: '' - ---- - -**Description of the false positive** - - - -**URL to the alert on the project page on LGTM.com** - - diff --git a/.github/ISSUE_TEMPLATE/ql---general.md b/.github/ISSUE_TEMPLATE/ql---general.md index 1d5b7d244f6..f68574485c1 100644 --- a/.github/ISSUE_TEMPLATE/ql---general.md +++ b/.github/ISSUE_TEMPLATE/ql---general.md @@ -10,5 +10,5 @@ assignees: '' **Description of the issue** +If it is about a GitHub project, please include its URL. --> diff --git a/.github/ISSUE_TEMPLATE/ql--false-positive.md b/.github/ISSUE_TEMPLATE/ql--false-positive.md new file mode 100644 index 00000000000..b80590a1832 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ql--false-positive.md @@ -0,0 +1,36 @@ +--- +name: CodeQL false positive +about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.) +title: False positive +labels: false-positive +assignees: '' + +--- + +**Description of the false positive** + + + +**Code samples or links to source code** + + + +**URL to the alert on GitHub code scanning (optional)** + + diff --git a/.github/actions/cache-query-compilation/action.yml b/.github/actions/cache-query-compilation/action.yml new file mode 100644 index 00000000000..95f25cbfc68 --- /dev/null +++ b/.github/actions/cache-query-compilation/action.yml @@ -0,0 +1,55 @@ +name: Cache query compilation +description: Caches CodeQL compilation caches - should be run both on PRs and pushes to main. + +inputs: + key: + description: 'The cache key to use - should be unique to the workflow' + required: true + +outputs: + cache-dir: + description: "The directory where the cache was stored" + value: ${{ steps.fill-compilation-dir.outputs.compdir }} + +runs: + using: composite + steps: + # calculate the merge-base with main, in a way that works both on PRs and pushes to main. + - name: Calculate merge-base + shell: bash + if: ${{ github.event_name == 'pull_request' }} + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") + echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV + - name: Restore read-only cache (PR) + if: ${{ github.event_name == 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + with: + path: '**/.cache' + read-only: true + key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} + restore-keys: | + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }} + codeql-compile-${{ inputs.key }}-${{ github.base_ref }}- + codeql-compile-${{ inputs.key }}-main- + - name: Fill cache (push) + if: ${{ github.event_name != 'pull_request' }} + uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6 + with: + path: '**/.cache' + key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main + restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation. + codeql-compile-${{ inputs.key }}-${{ github.ref_name }}- + codeql-compile-${{ inputs.key }}-main- + - name: Fill compilation cache directory + id: fill-compilation-dir + shell: bash + run: | + # Move all the existing cache into another folder, so we only preserve the cache for the current queries. + node $GITHUB_WORKSPACE/.github/actions/cache-query-compilation/move-caches.js ${COMBINED_CACHE_DIR} + + echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT + env: + COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir diff --git a/.github/actions/cache-query-compilation/move-caches.js b/.github/actions/cache-query-compilation/move-caches.js new file mode 100644 index 00000000000..67fc503cdc0 --- /dev/null +++ b/.github/actions/cache-query-compilation/move-caches.js @@ -0,0 +1,75 @@ +// # Move all the existing cache into another folder, so we only preserve the cache for the current queries. +// mkdir -p ${COMBINED_CACHE_DIR} +// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. +// # copy the contents of the .cache folders into the combined cache folder. +// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files +// # clean up the .cache folders +// rm -rf **/.cache/* + +const fs = require("fs"); +const path = require("path"); + +// the first argv is the cache folder to create. +const COMBINED_CACHE_DIR = process.argv[2]; + +function* walkCaches(dir) { + const files = fs.readdirSync(dir, { withFileTypes: true }); + for (const file of files) { + if (file.isDirectory()) { + const filePath = path.join(dir, file.name); + yield* walkCaches(filePath); + if (file.name === ".cache") { + yield filePath; + } + } + } +} + +async function copyDir(src, dest) { + for await (const file of await fs.promises.readdir(src, { withFileTypes: true })) { + const srcPath = path.join(src, file.name); + const destPath = path.join(dest, file.name); + if (file.isDirectory()) { + if (!fs.existsSync(destPath)) { + fs.mkdirSync(destPath); + } + await copyDir(srcPath, destPath); + } else { + await fs.promises.copyFile(srcPath, destPath); + } + } +} + +async function main() { + const cacheDirs = [...walkCaches(".")]; + + for (const dir of cacheDirs) { + console.log(`Found .cache dir at ${dir}`); + } + + // mkdir -p ${COMBINED_CACHE_DIR} + fs.mkdirSync(COMBINED_CACHE_DIR, { recursive: true }); + + // rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty. + await Promise.all( + cacheDirs.map((cacheDir) => + (async function () { + await fs.promises.rm(path.join(cacheDir, "lock"), { force: true }); + await fs.promises.rm(path.join(cacheDir, "size"), { force: true }); + })() + ) + ); + + // # copy the contents of the .cache folders into the combined cache folder. + // cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files + await Promise.all( + cacheDirs.map((cacheDir) => copyDir(cacheDir, COMBINED_CACHE_DIR)) + ); + + // # clean up the .cache folders + // rm -rf **/.cache/* + await Promise.all( + cacheDirs.map((cacheDir) => fs.promises.rm(cacheDir, { recursive: true })) + ); +} +main(); diff --git a/.github/actions/find-latest-bundle/action.yml b/.github/actions/find-latest-bundle/action.yml new file mode 100644 index 00000000000..59e16a6d3cb --- /dev/null +++ b/.github/actions/find-latest-bundle/action.yml @@ -0,0 +1,26 @@ +name: Find Latest CodeQL Bundle +description: Finds the URL of the latest released version of the CodeQL bundle. +outputs: + url: + description: The download URL of the latest CodeQL bundle release + value: ${{ steps.find-latest.outputs.url }} +runs: + using: composite + steps: + - name: Find Latest Release + id: find-latest + shell: pwsh + run: | + $Latest = gh release list --repo github/codeql-action --exclude-drafts --limit 1000 | + ForEach-Object { $C = $_ -split "`t"; return @{ type = $C[1]; tag = $C[2]; } } | + Where-Object { $_.type -eq 'Latest' } + + $Tag = $Latest.tag + if ($Tag -eq '') { + throw 'Failed to find latest bundle release.' + } + + Write-Output "Latest bundle tag is '${Tag}'." + "url=https://github.com/github/codeql-action/releases/download/${Tag}/codeql-bundle-linux64.tar.gz" >> $env:GITHUB_OUTPUT + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/atm-check-query-suite.yml b/.github/workflows/atm-check-query-suite.yml index 7317746fe62..ed93a6f8f2f 100644 --- a/.github/workflows/atm-check-query-suite.yml +++ b/.github/workflows/atm-check-query-suite.yml @@ -13,7 +13,7 @@ on: jobs: atm-check-query-suite: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 @@ -23,6 +23,12 @@ jobs: with: channel: release + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: atm-suite + - name: Install ATM model run: | set -exu @@ -50,10 +56,13 @@ jobs: echo "SARIF_PATH=${SARIF_PATH}" >> "${GITHUB_ENV}" codeql database analyze \ + --threads=0 \ + --ram 50000 \ --format sarif-latest \ --output "${SARIF_PATH}" \ --sarif-group-rules-by-pack \ -vv \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ "${DB_PATH}" \ "${QUERY_PACK}/${QUERY_SUITE}" diff --git a/.github/workflows/check-query-ids.yml b/.github/workflows/check-query-ids.yml new file mode 100644 index 00000000000..9ce9ed5ba85 --- /dev/null +++ b/.github/workflows/check-query-ids.yml @@ -0,0 +1,21 @@ +name: Check query IDs + +on: + pull_request: + paths: + - "**/src/**/*.ql" + - misc/scripts/check-query-ids.py + - .github/workflows/check-query-ids.yml + branches: + - main + - "rc/*" + workflow_dispatch: + +jobs: + check: + name: Check query IDs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Check for duplicate query IDs + run: python3 misc/scripts/check-query-ids.py diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml index 73d1e5ac2cc..96d8e4cc30b 100644 --- a/.github/workflows/compile-queries.yml +++ b/.github/workflows/compile-queries.yml @@ -14,46 +14,24 @@ jobs: steps: - uses: actions/checkout@v3 - # calculate the merge-base with main, in a way that works both on PRs and pushes to main. - - name: Calculate merge-base - if: ${{ github.event_name == 'pull_request' }} - env: - BASE_BRANCH: ${{ github.base_ref }} - run: | - MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ") - echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV - - name: Read CodeQL query compilation - PR - if: ${{ github.event_name == 'pull_request' }} - uses: actions/cache@v3 - with: - path: '*/ql/src/.cache' - key: codeql-compile-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here. - restore-keys: | - codeql-compile-${{ github.base_ref }}-${{ env.merge-base }} - codeql-compile-${{ github.base_ref }}- - codeql-compile-main- - - name: Fill CodeQL query compilation cache - main - if: ${{ github.event_name != 'pull_request' }} - uses: actions/cache@v3 - with: - path: '*/ql/src/.cache' - key: codeql-compile-${{ github.ref_name }}-${{ github.sha }} # just fill on main - restore-keys: | # restore from another random commit, to speed up compilation. - codeql-compile-${{ github.ref_name }}- - codeql-compile-main- - name: Setup CodeQL uses: ./.github/actions/fetch-codeql with: channel: 'release' + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: all-queries - name: check formatting - run: codeql query format */ql/{src,lib,test}/**/*.{qll,ql} --check-only + run: find */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 codeql query format --check-only - name: compile queries - check-only # run with --check-only if running in a PR (github.sha != main) if : ${{ github.event_name == 'pull_request' }} shell: bash - run: codeql query compile -j0 */ql/src --keep-going --warnings=error --check-only + run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" - name: compile queries - full # do full compile if running on main - this populates the cache if : ${{ github.event_name != 'pull_request' }} shell: bash - run: codeql query compile -j0 */ql/src --keep-going --warnings=error \ No newline at end of file + run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml new file mode 100644 index 00000000000..b9bbf930add --- /dev/null +++ b/.github/workflows/csharp-qltest.yml @@ -0,0 +1,86 @@ +name: "C#: Run QL Tests" + +on: + push: + paths: + - "csharp/**" + - "shared/**" + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml + branches: + - main + - "rc/*" + pull_request: + paths: + - "csharp/**" + - "shared/**" + - .github/workflows/csharp-qltest.yml + - .github/actions/fetch-codeql/action.yml + - codeql-workspace.yml + branches: + - main + - "rc/*" + +defaults: + run: + working-directory: csharp + +jobs: + qlupgrade: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - name: Check DB upgrade scripts + run: | + echo >empty.trap + codeql dataset import -S ql/lib/upgrades/initial/semmlecode.csharp.dbscheme testdb empty.trap + codeql dataset upgrade testdb --additional-packs ql/lib + diff -q testdb/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme + - name: Check DB downgrade scripts + run: | + echo >empty.trap + rm -rf testdb; codeql dataset import -S ql/lib/semmlecode.csharp.dbscheme testdb empty.trap + codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \ + --dbscheme=ql/lib/semmlecode.csharp.dbscheme --target-dbscheme=downgrades/initial/semmlecode.csharp.dbscheme | + xargs codeql execute upgrades testdb + diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme + qltest: + runs-on: ubuntu-latest-xl + strategy: + fail-fast: false + matrix: + slice: ["1/2", "2/2"] + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - uses: ./csharp/actions/create-extractor-pack + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: csharp-qltest-${{ matrix.slice }} + - name: Run QL tests + run: | + CODEQL_PATH=$(gh codeql version --format=json | jq -r .unpackedLocation) + # The legacy ASP extractor is not in this repo, so take the one from the nightly build + mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools" + # Safe guard against using the bundled extractor + rm -rf "$CODEQL_PATH/csharp" + codeql test run --threads=0 --ram 50000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" + env: + GITHUB_TOKEN: ${{ github.token }} + unit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.202 + - name: Extractor unit tests + run: | + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Util.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Extraction.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests" + dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests" diff --git a/.github/workflows/go-tests-other-os.yml b/.github/workflows/go-tests-other-os.yml new file mode 100644 index 00000000000..edf6eb63d49 --- /dev/null +++ b/.github/workflows/go-tests-other-os.yml @@ -0,0 +1,80 @@ +name: "Go: Run Tests - Other OS" +on: + pull_request: + paths: + - "go/**" + - "!go/ql/**" # don't run other-os if only ql/ files changed + - .github/workflows/go-tests-other-os.yml + - .github/actions/** + - codeql-workspace.yml +jobs: + test-mac: + name: Test MacOS + runs-on: macos-latest + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v3 + with: + go-version: 1.19 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" + + test-win: + name: Test Windows + runs-on: windows-latest-xl + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v3 + with: + go-version: 1.19 + id: go + + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql + + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + + - name: Build + run: | + cd go + make + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: go-qltest + + - name: Test + run: | + cd go + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 3cc61eafa5c..eceabb0410a 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -1,15 +1,24 @@ name: "Go: Run Tests" on: + push: + paths: + - "go/**" + - .github/workflows/go-tests.yml + - .github/actions/** + - codeql-workspace.yml + branches: + - main + - "rc/*" pull_request: paths: - "go/**" - .github/workflows/go-tests.yml - - .github/actions/fetch-codeql/action.yml + - .github/actions/** - codeql-workspace.yml jobs: test-linux: name: Test Linux (Ubuntu) - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - name: Set up Go 1.19 uses: actions/setup-go@v3 @@ -32,7 +41,7 @@ jobs: cd go make - - name: Check that all QL and Go code is autoformatted + - name: Check that all Go code is autoformatted run: | cd go make check-formatting @@ -48,67 +57,13 @@ jobs: name: qhelp-markdown path: go/qhelp-out/**/*.md - - name: Test - run: | - cd go - make test - - test-mac: - name: Test MacOS - runs-on: macos-latest - steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation with: - go-version: 1.19 - id: go - - - name: Check out code - uses: actions/checkout@v2 - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - cd go - make + key: go-qltest - name: Test run: | cd go - make test - - test-win: - name: Test Windows - runs-on: windows-2019 - steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 - with: - go-version: 1.19 - id: go - - - name: Check out code - uses: actions/checkout@v2 - - - name: Set up CodeQL CLI - uses: ./.github/actions/fetch-codeql - - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - - name: Build - run: | - cd go - make - - - name: Test - run: | - cd go - make test + make test cache="${{ steps.query-cache.outputs.cache-dir }}" diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index c932432530b..90cb5691126 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -23,22 +23,9 @@ defaults: working-directory: javascript/ql/experimental/adaptivethreatmodeling jobs: - qlformat: - name: Check QL formatting - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: ./.github/actions/fetch-codeql - - - name: Check QL formatting - run: | - find . "(" -name "*.ql" -or -name "*.qll" ")" -print0 | \ - xargs -0 codeql query format --check-only - - qlcompile: - name: Check QL compilation - runs-on: ubuntu-latest + qltest: + name: Test QL + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 @@ -46,36 +33,33 @@ jobs: - name: Install pack dependencies run: | - for pack in modelbuilding src; do + for pack in modelbuilding src test; do codeql pack install --mode verify -- "${pack}" done + + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: js-ml-test - name: Check QL compilation run: | codeql query compile \ --check-only \ - --ram 5120 \ + --ram 50000 \ --additional-packs "${{ github.workspace }}" \ --threads=0 \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ lib modelbuilding src - qltest: - name: Run QL tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: ./.github/actions/fetch-codeql - - - name: Install pack dependencies - run: codeql pack install -- test - - name: Run QL tests run: | codeql test run \ --threads=0 \ - --ram 5120 \ + --ram 50000 \ --additional-packs "${{ github.workspace }}" \ + --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \ -- \ - test + test \ No newline at end of file diff --git a/.github/workflows/mad_modelDiff.yml b/.github/workflows/mad_modelDiff.yml index 04e5f486866..586b1576bd6 100644 --- a/.github/workflows/mad_modelDiff.yml +++ b/.github/workflows/mad_modelDiff.yml @@ -61,8 +61,8 @@ jobs: DATABASE=$2 cd codeql-$QL_VARIANT SHORTNAME=`basename $DATABASE` - python java/ql/src/utils/model-generator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE $MODELS/${SHORTNAME}.qll - mv $MODELS/${SHORTNAME}.qll $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.qll + python java/ql/src/utils/model-generator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE ${SHORTNAME}.temp.model.yml + mv java/ql/lib/ext/generated/${SHORTNAME}.temp.model.yml $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.model.yml cd .. } @@ -85,16 +85,16 @@ jobs: set -x MODELS=`pwd`/tmp-models ls -1 tmp-models/ - for m in $MODELS/*_main.qll ; do + for m in $MODELS/*_main.model.yml ; do t="${m/main/"pr"}" basename=`basename $m` - name="diff_${basename/_main.qll/""}" + name="diff_${basename/_main.model.yml/""}" (diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true done - uses: actions/upload-artifact@v3 with: name: models - path: tmp-models/*.qll + path: tmp-models/*.model.yml retention-days: 20 - uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/mad_regenerate-models.yml b/.github/workflows/mad_regenerate-models.yml index 0abc8936911..d92e3652d5c 100644 --- a/.github/workflows/mad_regenerate-models.yml +++ b/.github/workflows/mad_regenerate-models.yml @@ -53,7 +53,7 @@ jobs: java/ql/src/utils/model-generator/RegenerateModels.py "${SLUG}" dbs/${SHORTNAME} - name: Stage changes run: | - find java -name "*.qll" -print0 | xargs -0 git add + find java -name "*.model.yml" -print0 | xargs -0 git add git status git diff --cached > models.patch - uses: actions/upload-artifact@v3 diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 701dc4d612c..29b8bc16300 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -22,11 +22,15 @@ jobs: steps: ### Build the queries ### - uses: actions/checkout@v3 + - name: Find latest bundle + id: find-latest-bundle + uses: ./.github/actions/find-latest-bundle - name: Find codeql id: find-codeql uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683 with: languages: javascript # does not matter + tools: ${{ steps.find-latest-bundle.outputs.url }} - name: Get CodeQL version id: get-codeql-version run: | @@ -138,6 +142,7 @@ jobs: languages: ql db-location: ${{ runner.temp }}/db config-file: ./ql-for-ql-config.yml + tools: ${{ steps.find-latest-bundle.outputs.url }} - name: Move pack cache run: | cp -r ${PACK}/.cache ql/ql/src/.cache diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml index b820d00a3e4..ce7963e8f79 100644 --- a/.github/workflows/ql-for-ql-tests.yml +++ b/.github/workflows/ql-for-ql-tests.yml @@ -47,8 +47,3 @@ jobs: find ql/ql/src "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only env: CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} - - name: Check QL compilation - run: | - "${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples" - env: - CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index f7ec215a44a..f561af9c13b 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -48,7 +48,19 @@ jobs: run: | brew install gnu-tar echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH + - name: Cache entire extractor + uses: actions/cache@v3 + id: cache-extractor + with: + path: | + ruby/target/release/ruby-autobuilder + ruby/target/release/ruby-autobuilder.exe + ruby/target/release/ruby-extractor + ruby/target/release/ruby-extractor.exe + ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll + key: ${{ runner.os }}-ruby-extractor-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}--${{ hashFiles('ruby/**/*.rs') }} - uses: actions/cache@v3 + if: steps.cache-extractor.outputs.cache-hit != 'true' with: path: | ~/.cargo/registry @@ -56,15 +68,19 @@ jobs: ruby/target key: ${{ runner.os }}-ruby-rust-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }} - name: Check formatting + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo fmt --all -- --check - name: Build + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo build --verbose - name: Run tests + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo test --verbose - name: Release build + if: steps.cache-extractor.outputs.cache-hit != 'true' run: cargo build --release - name: Generate dbscheme - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}} run: target/release/ruby-generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll - uses: actions/upload-artifact@v3 if: ${{ matrix.os == 'ubuntu-latest' }} @@ -86,19 +102,24 @@ jobs: ruby/target/release/ruby-extractor.exe retention-days: 1 compile-queries: - runs-on: ubuntu-latest - env: - CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: ruby-build - name: Build Query Pack run: | + rm -rf target/packs codeql pack create ../shared/ssa --output target/packs codeql pack create ../misc/suite-helpers --output target/packs + codeql pack create ../shared/regex --output target/packs codeql pack create ql/lib --output target/packs - codeql pack create ql/src --output target/packs + codeql pack create -j0 ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 97235b722ba..370375cea93 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -4,7 +4,7 @@ on: push: paths: - "ruby/**" - - .github/workflows/ruby-qltest.yml + - .github/workflows/ruby-build.yml - .github/actions/fetch-codeql/action.yml - codeql-workspace.yml branches: @@ -28,23 +28,6 @@ defaults: working-directory: ruby jobs: - qlformat: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: ./.github/actions/fetch-codeql - - name: Check QL formatting - run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only - qlcompile: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: ./.github/actions/fetch-codeql - - name: Check QL compilation - run: | - codeql query compile --check-only --threads=0 --ram 5000 --warnings=error "ql/src" "ql/examples" - env: - GITHUB_TOKEN: ${{ github.token }} qlupgrade: runs-on: ubuntu-latest steps: @@ -65,17 +48,20 @@ jobs: xargs codeql execute upgrades testdb diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme qltest: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl strategy: fail-fast: false - matrix: - slice: ["1/2", "2/2"] steps: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql - uses: ./ruby/actions/create-extractor-pack + - name: Cache compilation cache + id: query-cache + uses: ./.github/actions/cache-query-compilation + with: + key: ruby-qltest - name: Run QL tests run: | - codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test + codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" env: GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 873b94d2118..de0f11f0521 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -7,95 +7,77 @@ on: - "misc/bazel/**" - "*.bazel*" - .github/workflows/swift.yml - - .github/actions/fetch-codeql/action.yml + - .github/actions/** - codeql-workspace.yml - .pre-commit-config.yaml - "!**/*.md" - "!**/*.qhelp" branches: - main + - rc/* + push: + paths: + - "swift/**" + - "misc/bazel/**" + - "*.bazel*" + - .github/workflows/swift.yml + - .github/actions/** + - codeql-workspace.yml + - "!**/*.md" + - "!**/*.qhelp" + branches: + - main + - rc/* jobs: - changes: - runs-on: ubuntu-latest - outputs: - codegen: ${{ steps.filter.outputs.codegen }} - ql: ${{ steps.filter.outputs.ql }} - steps: - - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 - id: filter - with: - filters: | - codegen: - - 'github/workflows/swift.yml' - - "misc/bazel/**" - - "*.bazel*" - - 'swift/actions/setup-env/**' - - '.pre-commit-config.yaml' - - 'swift/codegen/**' - - 'swift/schema.py' - - 'swift/**/*.dbscheme' - - 'swift/ql/lib/codeql/swift/elements.qll' - - 'swift/ql/lib/codeql/swift/elements/**' - - 'swift/ql/lib/codeql/swift/generated/**' - - 'swift/ql/test/extractor-tests/generated/**' - ql: - - 'github/workflows/swift.yml' - - 'swift/**/*.ql' - - 'swift/**/*.qll' # not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks # without waiting for the macOS build build-and-test-macos: runs-on: macos-12-xl steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/create-extractor-pack - - uses: ./swift/actions/run-quick-tests - - uses: ./swift/actions/print-unextracted + - uses: ./swift/actions/build-and-test build-and-test-linux: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/create-extractor-pack - - uses: ./swift/actions/run-quick-tests - - uses: ./swift/actions/print-unextracted + - uses: ./swift/actions/build-and-test qltests-linux: needs: build-and-test-linux - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-ql-tests qltests-macos: + if : ${{ github.event_name == 'pull_request' }} needs: build-and-test-macos runs-on: macos-12-xl - strategy: - fail-fast: false - matrix: - slice: ["1/2", "2/2"] steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-ql-tests - with: - flags: --slice ${{ matrix.slice }} integration-tests-linux: needs: build-and-test-linux - runs-on: ubuntu-latest + runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-integration-tests integration-tests-macos: + if : ${{ github.event_name == 'pull_request' }} needs: build-and-test-macos runs-on: macos-12-xl + timeout-minutes: 60 steps: - uses: actions/checkout@v3 - uses: ./swift/actions/run-integration-tests codegen: + if : ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest - needs: changes - if: ${{ needs.changes.outputs.codegen == 'true' }} steps: - uses: actions/checkout@v3 - - uses: ./swift/actions/setup-env + - uses: bazelbuild/setup-bazelisk@v2 + - uses: actions/setup-python@v4 + with: + python-version-file: 'swift/.python-version' - uses: pre-commit/action@v3.0.0 name: Check that python code is properly formatted with: @@ -111,13 +93,11 @@ jobs: - uses: actions/upload-artifact@v3 with: name: swift-generated-cpp-files - path: swift/generated-cpp-files/** - qlformat: + path: generated-cpp-files/** + database-upgrade-scripts: + if : ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest - needs: changes - if: ${{ needs.changes.outputs.ql == 'true' }} steps: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql - - name: Check QL formatting - run: find swift/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only + - uses: ./swift/actions/database-upgrade-scripts diff --git a/.gitignore b/.gitignore index 7b8532b00d2..c81e23fc7f8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,8 +27,6 @@ # It's useful (though not required) to be able to unpack codeql in the ql checkout itself /codeql/ -csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json - # Avoid committing cached package components .codeql diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50a6adf80d9..5f35c2c183b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: rev: v1.6.0 hooks: - id: autopep8 - files: ^swift/codegen/.*\.py + files: ^swift/.*\.py - repo: local hooks: @@ -44,7 +44,7 @@ repos: - id: swift-codegen name: Run Swift checked in code generation - files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)) + files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list) language: system entry: bazel run //swift/codegen -- --quiet pass_filenames: false diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b22c91bb77..1050c79b825 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "omnisharp.autoStart": false + "omnisharp.autoStart": false, + "cmake.sourceDirectory": "${workspaceFolder}/swift", + "cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build" } diff --git a/CODEOWNERS b/CODEOWNERS index a18b6a51305..42fb364418f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,20 +5,13 @@ /javascript/ @github/codeql-javascript /python/ @github/codeql-python /ruby/ @github/codeql-ruby -/swift/ @github/codeql-c +/swift/ @github/codeql-swift /java/kotlin-extractor/ @github/codeql-kotlin /java/kotlin-explorer/ @github/codeql-kotlin # ML-powered queries /javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers -# Notify members of codeql-go about PRs to the shared data-flow library files -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go -/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go - # CodeQL tools and associated docs /docs/codeql/codeql-cli/ @github/codeql-cli-reviewers /docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers @@ -45,4 +38,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers /.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers /.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers /.github/workflows/ruby-* @github/codeql-ruby -/.github/workflows/swift-* @github/codeql-c +/.github/workflows/swift.yml @github/codeql-swift diff --git a/codeql-workspace.yml b/codeql-workspace.yml index f93ed4ac5c8..c2258bd1363 100644 --- a/codeql-workspace.yml +++ b/codeql-workspace.yml @@ -25,7 +25,8 @@ provide: - "misc/suite-helpers/qlpack.yml" - "ruby/extractor-pack/codeql-extractor.yml" - "swift/extractor-pack/codeql-extractor.yml" - - "ql/extractor-pack/codeql-extractor.ym" + - "swift/integration-tests/qlpack.yml" + - "ql/extractor-pack/codeql-extractor.yml" versionPolicies: default: diff --git a/config/identical-files.json b/config/identical-files.json index f5ad906f340..afef0a923d5 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -1,5 +1,5 @@ { - "DataFlow Java/C++/C#/Python": [ + "DataFlow Java/C++/C#/Go/Python/Ruby/Swift": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll", "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll", @@ -27,6 +27,8 @@ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll", @@ -38,17 +40,18 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll" ], - "DataFlow Java/C++/C#/Python Common": [ + "DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll", "cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll", + "go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll", "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll" ], - "TaintTracking::Configuration Java/C++/C#/Python": [ + "TaintTracking::Configuration Java/C++/C#/Go/Python/Ruby/Swift": [ "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", @@ -62,6 +65,8 @@ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", @@ -72,7 +77,7 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" ], - "DataFlow Java/C++/C#/Python Consistency checks": [ + "DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [ "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll", "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll", "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll", @@ -82,9 +87,10 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll", "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll" ], - "DataFlow Java/C#/Ruby/Python/Swift Flow Summaries": [ + "DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [ "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", + "go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll", "python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll" @@ -464,6 +470,10 @@ "javascript/ql/src/Comments/CommentedOutCodeReferences.inc.qhelp", "python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp" ], + "ThreadResourceAbuse qhelp": [ + "java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp", + "java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp" + ], "IDE Contextual Queries": [ "cpp/ql/lib/IDEContextual.qll", "csharp/ql/lib/IDEContextual.qll", @@ -486,40 +496,6 @@ "python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll", "ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll" ], - "ReDoS Util Python/JS/Ruby/Java": [ - "javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll", - "python/ql/lib/semmle/python/security/regexp/NfaUtils.qll", - "ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll", - "java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll" - ], - "ReDoS Exponential Python/JS/Ruby/Java": [ - "javascript/ql/lib/semmle/javascript/security/regexp/ExponentialBackTracking.qll", - "python/ql/lib/semmle/python/security/regexp/ExponentialBackTracking.qll", - "ruby/ql/lib/codeql/ruby/security/regexp/ExponentialBackTracking.qll", - "java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll" - ], - "ReDoS Polynomial Python/JS/Ruby/Java": [ - "javascript/ql/lib/semmle/javascript/security/regexp/SuperlinearBackTracking.qll", - "python/ql/lib/semmle/python/security/regexp/SuperlinearBackTracking.qll", - "ruby/ql/lib/codeql/ruby/security/regexp/SuperlinearBackTracking.qll", - "java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll" - ], - "RegexpMatching Python/JS/Ruby": [ - "javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll", - "python/ql/lib/semmle/python/security/regexp/RegexpMatching.qll", - "ruby/ql/lib/codeql/ruby/security/regexp/RegexpMatching.qll" - ], - "BadTagFilterQuery Python/JS/Ruby": [ - "javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll", - "python/ql/lib/semmle/python/security/BadTagFilterQuery.qll", - "ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll" - ], - "OverlyLargeRange Python/JS/Ruby/Java": [ - "javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll", - "python/ql/lib/semmle/python/security/OverlyLargeRangeQuery.qll", - "ruby/ql/lib/codeql/ruby/security/OverlyLargeRangeQuery.qll", - "java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll" - ], "CFG": [ "csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll", "ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll", @@ -539,6 +515,7 @@ ], "AccessPathSyntax": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll", + "go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll", "java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll", "javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll", @@ -554,16 +531,16 @@ "ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll", "javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll" ], - "Hostname Regexp queries": [ - "javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll", - "python/ql/src/Security/CWE-020/HostnameRegexpShared.qll", - "ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll" - ], "ApiGraphModels": [ "javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll", "ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll", "python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll" ], + "ApiGraphModelsExtensions": [ + "javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsExtensions.qll", + "ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsExtensions.qll", + "python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsExtensions.qll" + ], "TaintedFormatStringQuery Ruby/JS": [ "javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll", "ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll" @@ -607,5 +584,9 @@ "IncompleteMultiCharacterSanitization JS/Ruby": [ "javascript/ql/lib/semmle/javascript/security/IncompleteMultiCharacterSanitizationQuery.qll", "ruby/ql/lib/codeql/ruby/security/IncompleteMultiCharacterSanitizationQuery.qll" + ], + "EncryptionKeySizes Python/Java": [ + "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", + "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ] } diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs index 76acba2eee4..def45890c9f 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs @@ -257,11 +257,11 @@ namespace Semmle.Autobuild.Cpp.Tests Actions.GetCurrentDirectory = cwd; Actions.IsWindows = isWindows; - var options = new AutobuildOptions(Actions, Language.Cpp); + var options = new CppAutobuildOptions(Actions); return new CppAutobuilder(Actions, options); } - void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun) + void TestAutobuilderScript(CppAutobuilder autobuilder, int expectedOutput, int commandsRun) { Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(Actions, StartCallback, EndCallback)); @@ -299,7 +299,7 @@ namespace Semmle.Autobuild.Cpp.Tests { Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1; Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0; - Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0; + Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0; Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = ""; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0; diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj index dc1d945521b..421ffdd96f4 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj @@ -11,11 +11,12 @@ - - + + all runtime; build; native; contentfiles; analyzers + diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs index 44c34656a2a..1503dedb376 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/CppAutobuilder.cs @@ -2,9 +2,26 @@ namespace Semmle.Autobuild.Cpp { - public class CppAutobuilder : Autobuilder + /// + /// Encapsulates C++ build options. + /// + public class CppAutobuildOptions : AutobuildOptionsShared { - public CppAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { } + public override Language Language => Language.Cpp; + + + /// + /// Reads options from environment variables. + /// Throws ArgumentOutOfRangeException for invalid arguments. + /// + public CppAutobuildOptions(IBuildActions actions) : base(actions) + { + } + } + + public class CppAutobuilder : Autobuilder + { + public CppAutobuilder(IBuildActions actions, CppAutobuildOptions options) : base(actions, options) { } public override BuildScript GetBuildScript() { diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs index 3f4627c53d5..a7556197bcd 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Program.cs @@ -11,14 +11,14 @@ namespace Semmle.Autobuild.Cpp try { var actions = SystemBuildActions.Instance; - var options = new AutobuildOptions(actions, Language.Cpp); + var options = new CppAutobuildOptions(actions); try { Console.WriteLine("CodeQL C++ autobuilder"); var builder = new CppAutobuilder(actions, options); return builder.AttemptBuild(); } - catch(InvalidEnvironmentException ex) + catch (InvalidEnvironmentException ex) { Console.WriteLine("The environment is invalid: {0}", ex.Message); } diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj index e417622707a..393d4141ab9 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj @@ -17,7 +17,7 @@ - + diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 0a7a31b8db9..6fa6f76aabd 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.6 + +No user-facing changes. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +No user-facing changes. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md b/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md new file mode 100644 index 00000000000..eb6bd755c2b --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-14-deprecate-ast-gvn.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- + + +* Deprecated `semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl`. Use `semmle.code.cpp.valuenumbering.GlobalValueNumbering`, which exposes the same API. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2022-11-16-must-flow.md b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md new file mode 100644 index 00000000000..0f87b8d8bcd --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-16-must-flow.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +The predicates in the `MustFlow::Configuration` class used by the `MustFlow` library (`semmle.code.cpp.ir.dataflow.MustFlow`) have changed to be defined directly in terms of the C++ IR instead of IR dataflow nodes. diff --git a/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md b/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..bf2d5a07de6 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getName` and `getShortName` predicates from the `Folder` class. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2022-11-25-deprecate-default-taint-tracking.md b/cpp/ql/lib/change-notes/2022-11-25-deprecate-default-taint-tracking.md new file mode 100644 index 00000000000..54d10d592d6 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-11-25-deprecate-default-taint-tracking.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- + +* Deprecated `semmle.code.cpp.ir.dataflow.DefaultTaintTracking`. Use `semmle.code.cpp.ir.dataflow.TaintTracking`. +* Deprecated `semmle.code.cpp.security.TaintTrackingImpl`. Use `semmle.code.cpp.ir.dataflow.TaintTracking`. diff --git a/cpp/ql/lib/change-notes/2022-12-08-support-getaddrinfo-dataflow.md b/cpp/ql/lib/change-notes/2022-12-08-support-getaddrinfo-dataflow.md new file mode 100644 index 00000000000..6d1a6499ee9 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-12-08-support-getaddrinfo-dataflow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `getaddrinfo` function is now recognized as a flow source. diff --git a/cpp/ql/lib/change-notes/2022-12-08-support-getenv-variants.md b/cpp/ql/lib/change-notes/2022-12-08-support-getenv-variants.md new file mode 100644 index 00000000000..c91d549ec8a --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-12-08-support-getenv-variants.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `secure_getenv` and `_wgetenv` functions are now recognized as local flow sources. diff --git a/cpp/ql/lib/change-notes/2022-12-08-support-scanf-dataflow.md b/cpp/ql/lib/change-notes/2022-12-08-support-scanf-dataflow.md new file mode 100644 index 00000000000..f8382f84c0f --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-12-08-support-scanf-dataflow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `scanf` and `fscanf` functions and their variants are now recognized as flow sources. diff --git a/cpp/ql/lib/change-notes/2022-12-09-generalize-argv-source.md b/cpp/ql/lib/change-notes/2022-12-09-generalize-argv-source.md new file mode 100644 index 00000000000..76fda20ec61 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-12-09-generalize-argv-source.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `ArgvSource` flow source has been generalized to handle cases where the argument vector of `main` is not named `argv`. diff --git a/cpp/ql/lib/change-notes/released/0.4.4.md b/cpp/ql/lib/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/cpp/ql/lib/change-notes/released/0.4.5.md b/cpp/ql/lib/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/cpp/ql/lib/change-notes/released/0.4.6.md b/cpp/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/cpp/ql/lib/definitions.qll b/cpp/ql/lib/definitions.qll index cb229d66ef1..e4a2aca98f6 100644 --- a/cpp/ql/lib/definitions.qll +++ b/cpp/ql/lib/definitions.qll @@ -12,8 +12,8 @@ import IDEContextual * * In some cases it is preferable to modify locations (the * `hasLocationInfo()` predicate) so that they are short, and - * non-overlapping with other locations that might be highlighted in - * the LGTM interface. + * non-overlapping with other locations that might be reported as + * code scanning alerts on GitHub. * * We need to give locations that may not be in the database, so * we use `hasLocationInfo()` rather than `getLocation()`. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9aa6a529a5b 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -915,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -1304,6 +1343,113 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; @@ -1336,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } } @@ -1350,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1362,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll index dde16ab5a2a..e85e0cd92ec 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll @@ -136,6 +136,18 @@ module Consistency { msg = "Local flow step does not preserve enclosing callable." } + query predicate readStepIsLocal(Node n1, Node n2, string msg) { + readStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Read step does not preserve enclosing callable." + } + + query predicate storeStepIsLocal(Node n1, Node n2, string msg) { + storeStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Store step does not preserve enclosing callable." + } + private DataFlowType typeRepr() { result = getNodeType(_) } query predicate compatibleTypesReflexive(DataFlowType t, string msg) { @@ -232,4 +244,25 @@ module Consistency { not callable = viableCallable(call) and not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) } + + query predicate uniqueParameterNodeAtPosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and + msg = "Parameters with overlapping positions." + } + + query predicate uniqueParameterNodePosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and + msg = "Parameter node with multiple positions." + } + + query predicate uniqueContentApprox(Content c, string msg) { + not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and + msg = "Non-unique content approximation." + } } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 69e08a9a5d2..58569ef2425 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -551,6 +551,13 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves */ predicate allowParameterReturnInSelf(ParameterNode p) { none() } +/** An approximated `Content`. */ +class ContentApprox = Unit; + +/** Gets an approximated value for content `c`. */ +pragma[inline] +ContentApprox getContentApprox(Content c) { any() } + private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { override predicate argHasPostUpdateExclude(ArgumentNode n) { // The rules for whether an IR argument gets a post-update node are too diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index f7e5abd25b7..f72edf2f806 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -292,12 +292,8 @@ module SemanticExprConfig { final Location getLocation() { result = super.getLocation() } } - private class ValueNumberBound extends Bound { - IRBound::ValueNumberBound bound; - - ValueNumberBound() { bound = this } - - override string toString() { result = bound.toString() } + private class ValueNumberBound extends Bound instanceof IRBound::ValueNumberBound { + override string toString() { result = IRBound::ValueNumberBound.super.toString() } } predicate zeroBound(Bound bound) { bound instanceof IRBound::ZeroBound } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll index 27c3083fecc..970a6c4e5a9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll @@ -33,23 +33,15 @@ abstract private class FlowSignDef extends SignDef { } /** An SSA definition whose sign is determined by the sign of that definitions source expression. */ -private class ExplicitSignDef extends FlowSignDef { - SemSsaExplicitUpdate update; - - ExplicitSignDef() { update = this } - - final override Sign getSign() { result = semExprSign(update.getSourceExpr()) } +private class ExplicitSignDef extends FlowSignDef instanceof SemSsaExplicitUpdate { + final override Sign getSign() { result = semExprSign(super.getSourceExpr()) } } /** An SSA Phi definition, whose sign is the union of the signs of its inputs. */ -private class PhiSignDef extends FlowSignDef { - SemSsaPhiNode phi; - - PhiSignDef() { phi = this } - +private class PhiSignDef extends FlowSignDef instanceof SemSsaPhiNode { final override Sign getSign() { exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge | - edge.phiInput(phi, inp) and + edge.phiInput(this, inp) and result = semSsaSign(inp, edge) ) } diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index ef1fd2099a3..ee8913624dc 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.4-dev +version: 0.5.0-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index e58467fac20..b2e4e0a41a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -189,18 +189,6 @@ class Folder extends Container, @folder { * Gets the URL of this folder. */ deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } - - /** - * DEPRECATED: use `getAbsolutePath` instead. - * Gets the name of this folder. - */ - deprecated string getName() { folders(underlyingElement(this), result) } - - /** - * DEPRECATED: use `getBaseName` instead. - * Gets the last part of the folder name. - */ - deprecated string getShortName() { result = this.getBaseName() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll index d063e8fa19c..51d2e294b36 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll @@ -397,11 +397,8 @@ private int lengthInBase16(float f) { /** * A class to represent format strings that occur as arguments to invocations of formatting functions. */ -class FormatLiteral extends Literal { - FormatLiteral() { - exists(FormattingFunctionCall ffc | ffc.getFormat() = this) and - this instanceof StringLiteral - } +class FormatLiteral extends Literal instanceof StringLiteral { + FormatLiteral() { exists(FormattingFunctionCall ffc | ffc.getFormat() = this) } /** * Gets the function call where this format string is used. diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll index 0d51c948170..376829c2eef 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll @@ -30,15 +30,12 @@ abstract class ScanfFunction extends Function { /** * The standard function `scanf` (and variations). */ -class Scanf extends ScanfFunction { +class Scanf extends ScanfFunction instanceof TopLevelFunction { Scanf() { - this instanceof TopLevelFunction and - ( - this.hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...) - this.hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...) - this.hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...) - this.hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...) - ) + this.hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...) + this.hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...) + this.hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...) + this.hasGlobalName("_wscanf_l") } override int getInputParameterIndex() { none() } @@ -49,15 +46,12 @@ class Scanf extends ScanfFunction { /** * The standard function `fscanf` (and variations). */ -class Fscanf extends ScanfFunction { +class Fscanf extends ScanfFunction instanceof TopLevelFunction { Fscanf() { - this instanceof TopLevelFunction and - ( - this.hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...) - this.hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...) - this.hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...) - this.hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...) - ) + this.hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...) + this.hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...) + this.hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...) + this.hasGlobalName("_fwscanf_l") } override int getInputParameterIndex() { result = 0 } @@ -68,15 +62,12 @@ class Fscanf extends ScanfFunction { /** * The standard function `sscanf` (and variations). */ -class Sscanf extends ScanfFunction { +class Sscanf extends ScanfFunction instanceof TopLevelFunction { Sscanf() { - this instanceof TopLevelFunction and - ( - this.hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...) - this.hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...) - this.hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...) - this.hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...) - ) + this.hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...) + this.hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...) + this.hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...) + this.hasGlobalName("_swscanf_l") } override int getInputParameterIndex() { result = 0 } @@ -87,17 +78,12 @@ class Sscanf extends ScanfFunction { /** * The standard(ish) function `snscanf` (and variations). */ -class Snscanf extends ScanfFunction { +class Snscanf extends ScanfFunction instanceof TopLevelFunction { Snscanf() { - this instanceof TopLevelFunction and - ( - this.hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...) - this.hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...) - this.hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...) - this.hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...) - // note that the max_amount is not a limit on the output length, it's an input length - // limit used with non null-terminated strings. - ) + this.hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...) + this.hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...) + this.hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...) + this.hasGlobalName("_snwscanf_l") } override int getInputParameterIndex() { result = 0 } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9aa6a529a5b 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -915,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -1304,6 +1343,113 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; @@ -1336,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } } @@ -1350,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1362,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll index dde16ab5a2a..e85e0cd92ec 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll @@ -136,6 +136,18 @@ module Consistency { msg = "Local flow step does not preserve enclosing callable." } + query predicate readStepIsLocal(Node n1, Node n2, string msg) { + readStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Read step does not preserve enclosing callable." + } + + query predicate storeStepIsLocal(Node n1, Node n2, string msg) { + storeStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Store step does not preserve enclosing callable." + } + private DataFlowType typeRepr() { result = getNodeType(_) } query predicate compatibleTypesReflexive(DataFlowType t, string msg) { @@ -232,4 +244,25 @@ module Consistency { not callable = viableCallable(call) and not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) } + + query predicate uniqueParameterNodeAtPosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and + msg = "Parameters with overlapping positions." + } + + query predicate uniqueParameterNodePosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and + msg = "Parameter node with multiple positions." + } + + query predicate uniqueContentApprox(Content c, string msg) { + not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and + msg = "Non-unique content approximation." + } } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 9ad3e835c38..1749de42f2c 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -296,6 +296,13 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves */ predicate allowParameterReturnInSelf(ParameterNode p) { none() } +/** An approximated `Content`. */ +class ContentApprox = Unit; + +/** Gets an approximated value for content `c`. */ +pragma[inline] +ContentApprox getContentApprox(Content c) { any() } + private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { override predicate argHasPostUpdateExclude(ArgumentNode n) { // Is the null pointer (or something that's not really a pointer) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index be5403734ce..8b559dbe932 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -1,642 +1,21 @@ /** + * DEPRECATED: Use `semmle.code.cpp.ir.dataflow.TaintTracking` as a replacement. + * * An IR taint tracking library that uses an IR DataFlow configuration to track * taint from user inputs as defined by `semmle.code.cpp.security.Security`. */ import cpp import semmle.code.cpp.security.Security -private import semmle.code.cpp.ir.dataflow.DataFlow -private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil -private import semmle.code.cpp.ir.dataflow.DataFlow3 -private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.ResolveCall -private import semmle.code.cpp.controlflow.IRGuards -private import semmle.code.cpp.models.interfaces.Taint -private import semmle.code.cpp.models.interfaces.DataFlow -private import semmle.code.cpp.ir.dataflow.TaintTracking -private import semmle.code.cpp.ir.dataflow.TaintTracking2 -private import semmle.code.cpp.ir.dataflow.TaintTracking3 -private import semmle.code.cpp.ir.dataflow.internal.ModelUtil +private import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl as DefaultTaintTrackingImpl -/** - * A predictable instruction is one where an external user can predict - * the value. For example, a literal in the source code is considered - * predictable. - */ -private predicate predictableInstruction(Instruction instr) { - instr instanceof ConstantInstruction - or - instr instanceof StringConstantInstruction - or - // This could be a conversion on a string literal - predictableInstruction(instr.(UnaryInstruction).getUnary()) -} +deprecated predicate predictableOnlyFlow = DefaultTaintTrackingImpl::predictableOnlyFlow/1; -/** - * Functions that we should only allow taint to flow through (to the return - * value) if all but the source argument are 'predictable'. This is done to - * emulate the old security library's implementation rather than due to any - * strong belief that this is the right approach. - * - * Note that the list itself is not very principled; it consists of all the - * functions listed in the old security library's [default] `isPureFunction` - * that have more than one argument, but are not in the old taint tracking - * library's `returnArgument` predicate. - */ -predicate predictableOnlyFlow(string name) { - name = - [ - "strcasestr", "strchnul", "strchr", "strchrnul", "strcmp", "strcspn", "strncmp", "strndup", - "strnlen", "strrchr", "strspn", "strstr", "strtod", "strtof", "strtol", "strtoll", "strtoq", - "strtoul" - ] -} +deprecated predicate tainted = DefaultTaintTrackingImpl::tainted/2; -private DataFlow::Node getNodeForSource(Expr source) { - isUserInput(source, _) and - result = getNodeForExpr(source) -} +deprecated predicate taintedIncludingGlobalVars = + DefaultTaintTrackingImpl::taintedIncludingGlobalVars/3; -private DataFlow::Node getNodeForExpr(Expr node) { - result = DataFlow::exprNode(node) - or - // Some of the sources in `isUserInput` are intended to match the value of - // an expression, while others (those modeled below) are intended to match - // the taint that propagates out of an argument, like the `char *` argument - // to `gets`. It's impossible here to tell which is which, but the "access - // to argv" source is definitely not intended to match an output argument, - // and it causes false positives if we let it. - // - // This case goes together with the similar (but not identical) rule in - // `nodeIsBarrierIn`. - result = DataFlow::definitionByReferenceNodeFromArgument(node) and - not argv(node.(VariableAccess).getTarget()) -} +deprecated predicate globalVarFromId = DefaultTaintTrackingImpl::globalVarFromId/1; -private class DefaultTaintTrackingCfg extends TaintTracking::Configuration { - DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" } - - override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } - - override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } - - override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - - override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } -} - -private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration { - ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" } - - override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } - - override predicate isSink(DataFlow::Node sink) { - sink.asVariable() instanceof GlobalOrNamespaceVariable - } - - override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { - writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) - or - readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) - } - - override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - - override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } -} - -private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration { - FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" } - - override predicate isSource(DataFlow::Node source) { - // This set of sources should be reasonably small, which is good for - // performance since the set of sinks is very large. - exists(ToGlobalVarTaintTrackingCfg otherCfg | otherCfg.hasFlowTo(source)) - } - - override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } - - override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { - // Additional step for flow out of variables. There is no flow _into_ - // variables in this configuration, so this step only serves to take flow - // out of a variable that's a source. - readsVariable(n2.asInstruction(), n1.asVariable()) - } - - override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - - override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } -} - -private predicate readsVariable(LoadInstruction load, Variable var) { - load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var -} - -private predicate writesVariable(StoreInstruction store, Variable var) { - store.getDestinationAddress().(VariableAddressInstruction).getAstVariable() = var -} - -/** - * A variable that has any kind of upper-bound check anywhere in the program. This is - * biased towards being inclusive because there are a lot of valid ways of doing an - * upper bounds checks if we don't consider where it occurs, for example: - * ``` - * if (x < 10) { sink(x); } - * - * if (10 > y) { sink(y); } - * - * if (z > 10) { z = 10; } - * sink(z); - * ``` - */ -// TODO: This coarse overapproximation, ported from the old taint tracking -// library, could be replaced with an actual semantic check that a particular -// variable _access_ is guarded by an upper-bound check. We probably don't want -// to do this right away since it could expose a lot of FPs that were -// previously suppressed by this predicate by coincidence. -private predicate hasUpperBoundsCheck(Variable var) { - exists(RelationalOperation oper, VariableAccess access | - oper.getAnOperand() = access and - access.getTarget() = var and - // Comparing to 0 is not an upper bound check - not oper.getAnOperand().getValue() = "0" - ) -} - -private predicate nodeIsBarrierEqualityCandidate( - DataFlow::Node node, Operand access, Variable checkedVar -) { - readsVariable(node.asInstruction(), checkedVar) and - any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true) -} - -cached -private module Cached { - cached - predicate nodeIsBarrier(DataFlow::Node node) { - exists(Variable checkedVar | - readsVariable(node.asInstruction(), checkedVar) and - hasUpperBoundsCheck(checkedVar) - ) - or - exists(Variable checkedVar, Operand access | - /* - * This node is guarded by a condition that forces the accessed variable - * to equal something else. For example: - * ``` - * x = taintsource() - * if (x == 10) { - * taintsink(x); // not considered tainted - * } - * ``` - */ - - nodeIsBarrierEqualityCandidate(node, access, checkedVar) and - readsVariable(access.getDef(), checkedVar) - ) - } - - cached - predicate nodeIsBarrierIn(DataFlow::Node node) { - // don't use dataflow into taint sources, as this leads to duplicate results. - exists(Expr source | isUserInput(source, _) | - node = DataFlow::exprNode(source) - or - // This case goes together with the similar (but not identical) rule in - // `getNodeForSource`. - node = DataFlow::definitionByReferenceNodeFromArgument(source) - ) - or - // don't use dataflow into binary instructions if both operands are unpredictable - exists(BinaryInstruction iTo | - iTo = node.asInstruction() and - not predictableInstruction(iTo.getLeft()) and - not predictableInstruction(iTo.getRight()) and - // propagate taint from either the pointer or the offset, regardless of predictability - not iTo instanceof PointerArithmeticInstruction - ) - or - // don't use dataflow through calls to pure functions if two or more operands - // are unpredictable - exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo | - iTo = node.asInstruction() and - isPureFunction(iTo.getStaticCallTarget().getName()) and - iFrom1 = iTo.getAnArgument() and - iFrom2 = iTo.getAnArgument() and - not predictableInstruction(iFrom1) and - not predictableInstruction(iFrom2) and - iFrom1 != iFrom2 - ) - } - - cached - Element adjustedSink(DataFlow::Node sink) { - // TODO: is it more appropriate to use asConvertedExpr here and avoid - // `getConversion*`? Or will that cause us to miss some cases where there's - // flow to a conversion (like a `ReferenceDereferenceExpr`) and we want to - // pretend there was flow to the converted `Expr` for the sake of - // compatibility. - sink.asExpr().getConversion*() = result - or - // For compatibility, send flow from arguments to parameters, even for - // functions with no body. - exists(FunctionCall call, int i | - sink.asExpr() = call.getArgument(pragma[only_bind_into](i)) and - result = resolveCall(call).getParameter(pragma[only_bind_into](i)) - ) - or - // For compatibility, send flow into a `Variable` if there is flow to any - // Load or Store of that variable. - exists(CopyInstruction copy | - copy.getSourceValue() = sink.asInstruction() and - ( - readsVariable(copy, result) or - writesVariable(copy, result) - ) and - not hasUpperBoundsCheck(result) - ) - or - // For compatibility, send flow into a `NotExpr` even if it's part of a - // short-circuiting condition and thus might get skipped. - result.(NotExpr).getOperand() = sink.asExpr() - or - // Taint postfix and prefix crement operations when their operand is tainted. - result.(CrementOperation).getAnOperand() = sink.asExpr() - or - // Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted. - result.(AssignOperation).getAnOperand() = sink.asExpr() - or - result = - sink.asOperand() - .(SideEffectOperand) - .getUse() - .(ReadSideEffectInstruction) - .getArgumentDef() - .getUnconvertedResultExpression() - } - - /** - * Step to return value of a modeled function when an input taints the - * dereference of the return value. - */ - cached - predicate additionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { - exists(CallInstruction call, Function func, FunctionInput modelIn, FunctionOutput modelOut | - n1.asOperand() = callInput(call, modelIn) and - ( - func.(TaintFunction).hasTaintFlow(modelIn, modelOut) - or - func.(DataFlowFunction).hasDataFlow(modelIn, modelOut) - ) and - call.getStaticCallTarget() = func and - modelOut.isReturnValueDeref() and - call = n2.asInstruction() - ) - } -} - -private import Cached - -/** - * Holds if `tainted` may contain taint from `source`. - * - * A tainted expression is either directly user input, or is - * computed from user input in a way that users can probably - * control the exact output of the computation. - * - * This doesn't include data flow through global variables. - * If you need that you must call `taintedIncludingGlobalVars`. - */ -cached -predicate tainted(Expr source, Element tainted) { - exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink | - cfg.hasFlow(getNodeForSource(source), sink) and - tainted = adjustedSink(sink) - ) -} - -/** - * Holds if `tainted` may contain taint from `source`, where the taint passed - * through a global variable named `globalVar`. - * - * A tainted expression is either directly user input, or is - * computed from user input in a way that users can probably - * control the exact output of the computation. - * - * This version gives the same results as tainted but also includes - * data flow through global variables. - * - * The parameter `globalVar` is the qualified name of the last global variable - * used to move the value from source to tainted. If the taint did not pass - * through a global variable, then `globalVar = ""`. - */ -cached -predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) { - tainted(source, tainted) and - globalVar = "" - or - exists( - ToGlobalVarTaintTrackingCfg toCfg, FromGlobalVarTaintTrackingCfg fromCfg, - DataFlow::VariableNode variableNode, GlobalOrNamespaceVariable global, DataFlow::Node sink - | - global = variableNode.getVariable() and - toCfg.hasFlow(getNodeForSource(source), variableNode) and - fromCfg.hasFlow(variableNode, sink) and - tainted = adjustedSink(sink) and - global = globalVarFromId(globalVar) - ) -} - -/** - * Gets the global variable whose qualified name is `id`. Use this predicate - * together with `taintedIncludingGlobalVars`. Example: - * - * ``` - * exists(string varName | - * taintedIncludingGlobalVars(source, tainted, varName) and - * var = globalVarFromId(varName) - * ) - * ``` - */ -GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() } - -/** - * Provides definitions for augmenting source/sink pairs with data-flow paths - * between them. From a `@kind path-problem` query, import this module in the - * global scope, extend `TaintTrackingConfiguration`, and use `taintedWithPath` - * in place of `tainted`. - * - * Importing this module will also import the query predicates that contain the - * taint paths. - */ -module TaintedWithPath { - private newtype TSingleton = MkSingleton() - - /** - * A taint-tracking configuration that matches sources and sinks in the same - * way as the `tainted` predicate. - * - * Override `isSink` and `taintThroughGlobals` as needed, but do not provide - * a characteristic predicate. - */ - class TaintTrackingConfiguration extends TSingleton { - /** Override this to specify which elements are sources in this configuration. */ - predicate isSource(Expr source) { exists(getNodeForSource(source)) } - - /** Override this to specify which elements are sinks in this configuration. */ - abstract predicate isSink(Element e); - - /** Override this to specify which expressions are barriers in this configuration. */ - predicate isBarrier(Expr e) { nodeIsBarrier(getNodeForExpr(e)) } - - /** - * Override this predicate to `any()` to allow taint to flow through global - * variables. - */ - predicate taintThroughGlobals() { none() } - - /** Gets a textual representation of this element. */ - string toString() { result = "TaintTrackingConfiguration" } - } - - private class AdjustedConfiguration extends TaintTracking3::Configuration { - AdjustedConfiguration() { this = "AdjustedConfiguration" } - - override predicate isSource(DataFlow::Node source) { - exists(TaintTrackingConfiguration cfg, Expr e | - cfg.isSource(e) and source = getNodeForExpr(e) - ) - } - - override predicate isSink(DataFlow::Node sink) { - exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink))) - } - - override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { - // Steps into and out of global variables - exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() | - writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) - or - readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) - ) - or - additionalTaintStep(n1, n2) - } - - override predicate isSanitizer(DataFlow::Node node) { - exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e)) - } - - override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } - } - - /* - * A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the - * inverse of) `adjustedSink`. For example, an `Expr` maps to all its - * conversions, and a `Variable` maps to all loads and stores from it. Because - * the path node is part of the tuple that constitutes the alert, this leads - * to duplicate alerts. - * - * To avoid showing duplicates, we edit the graph to replace the final node - * coming from the data-flow library with a node that matches exactly the - * `Element` sink that's requested. - * - * The same is done for sources. - */ - - private newtype TPathNode = - TWrapPathNode(DataFlow3::PathNode n) or - // There's a single newtype constructor for both sources and sinks since - // that makes it easiest to deal with the case where source = sink. - TEndpointPathNode(Element e) { - exists(AdjustedConfiguration cfg, DataFlow3::Node sourceNode, DataFlow3::Node sinkNode | - cfg.hasFlow(sourceNode, sinkNode) - | - sourceNode = getNodeForExpr(e) and - exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e)) - or - e = adjustedSink(sinkNode) and - exists(TaintTrackingConfiguration ttCfg | ttCfg.isSink(e)) - ) - } - - /** An opaque type used for the nodes of a data-flow path. */ - class PathNode extends TPathNode { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() - } - } - - /** - * INTERNAL: Do not use. - */ - module Private { - /** Gets a predecessor `PathNode` of `pathNode`, if any. */ - PathNode getAPredecessor(PathNode pathNode) { edges(result, pathNode) } - - /** Gets the element that `pathNode` wraps, if any. */ - Element getElementFromPathNode(PathNode pathNode) { - exists(DataFlow::Node node | node = pathNode.(WrapPathNode).inner().getNode() | - result = node.asInstruction().getAst() - or - result = node.asOperand().getDef().getAst() - ) - or - result = pathNode.(EndpointPathNode).inner() - } - } - - private class WrapPathNode extends PathNode, TWrapPathNode { - DataFlow3::PathNode inner() { this = TWrapPathNode(result) } - - override string toString() { result = this.inner().toString() } - - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.inner().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - } - - private class EndpointPathNode extends PathNode, TEndpointPathNode { - Expr inner() { this = TEndpointPathNode(result) } - - override string toString() { result = this.inner().toString() } - - override predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.inner() - .getLocation() - .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - } - - /** A PathNode whose `Element` is a source. It may also be a sink. */ - private class InitialPathNode extends EndpointPathNode { - InitialPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSource(this.inner())) } - } - - /** A PathNode whose `Element` is a sink. It may also be a source. */ - private class FinalPathNode extends EndpointPathNode { - FinalPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSink(this.inner())) } - } - - /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { - DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), b.(WrapPathNode).inner()) - or - // To avoid showing trivial-looking steps, we _replace_ the last node instead - // of adding an edge out of it. - exists(WrapPathNode sinkNode | - DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), sinkNode.inner()) and - b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) - ) - or - // Same for the first node - exists(WrapPathNode sourceNode | - DataFlow3::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and - sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) - ) - or - // Finally, handle the case where the path goes directly from a source to a - // sink, meaning that they both need to be translated. - exists(WrapPathNode sinkNode, WrapPathNode sourceNode | - DataFlow3::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and - sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) and - b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) - ) - } - - /** - * Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow - * from `par` to `ret` within it, in the graph of data flow path explanations. - */ - query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { - DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), - ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) - or - // To avoid showing trivial-looking steps, we _replace_ the last node instead - // of adding an edge out of it. - exists(WrapPathNode sinkNode | - DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), - ret.(WrapPathNode).inner(), sinkNode.inner()) and - out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) - ) - or - // Same for the first node - exists(WrapPathNode sourceNode | - DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), - ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and - sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) - ) - or - // Finally, handle the case where the path goes directly from a source to a - // sink, meaning that they both need to be translated. - exists(WrapPathNode sinkNode, WrapPathNode sourceNode | - DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), - ret.(WrapPathNode).inner(), sinkNode.inner()) and - sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and - out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) - ) - } - - /** Holds if `n` is a node in the graph of data flow path explanations. */ - query predicate nodes(PathNode n, string key, string val) { - key = "semmle.label" and val = n.toString() - } - - /** - * Holds if `tainted` may contain taint from `source`, where `sourceNode` and - * `sinkNode` are the corresponding `PathNode`s that can be used in a query - * to provide path explanations. Extend `TaintTrackingConfiguration` to use - * this predicate. - * - * A tainted expression is either directly user input, or is computed from - * user input in a way that users can probably control the exact output of - * the computation. - */ - predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) { - exists(AdjustedConfiguration cfg, DataFlow3::Node flowSource, DataFlow3::Node flowSink | - source = sourceNode.(InitialPathNode).inner() and - flowSource = getNodeForExpr(source) and - cfg.hasFlow(flowSource, flowSink) and - tainted = adjustedSink(flowSink) and - tainted = sinkNode.(FinalPathNode).inner() - ) - } - - private predicate isGlobalVariablePathNode(WrapPathNode n) { - n.inner().getNode().asVariable() instanceof GlobalOrNamespaceVariable - } - - private predicate edgesWithoutGlobals(PathNode a, PathNode b) { - edges(a, b) and - not isGlobalVariablePathNode(a) and - not isGlobalVariablePathNode(b) - } - - /** - * Holds if `tainted` can be reached from a taint source without passing - * through a global variable. - */ - predicate taintedWithoutGlobals(Element tainted) { - exists(AdjustedConfiguration cfg, PathNode sourceNode, FinalPathNode sinkNode | - cfg.isSource(sourceNode.(WrapPathNode).inner().getNode()) and - edgesWithoutGlobals+(sourceNode, sinkNode) and - tainted = sinkNode.inner() - ) - } -} +deprecated module TaintedWithPath = DefaultTaintTrackingImpl::TaintedWithPath; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll index 08ee06acdda..904701144ca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll @@ -5,7 +5,6 @@ */ private import cpp -import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.IR /** @@ -25,18 +24,18 @@ abstract class MustFlowConfiguration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(DataFlow::Node source); + abstract predicate isSource(Instruction source); /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(DataFlow::Node sink); + abstract predicate isSink(Operand sink); /** * Holds if the additional flow step from `node1` to `node2` must be taken * into account in the analysis. */ - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + predicate isAdditionalFlowStep(Operand node1, Instruction node2) { none() } /** Holds if this configuration allows flow from arguments to parameters. */ predicate allowInterproceduralFlow() { any() } @@ -48,17 +47,17 @@ abstract class MustFlowConfiguration extends string { * included in the module `PathGraph`. */ final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) { - this.isSource(source.getNode()) and + this.isSource(source.getInstruction()) and source.getASuccessor+() = sink } } /** Holds if `node` flows from a source. */ pragma[nomagic] -private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration config) { +private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) { config.isSource(node) or - exists(DataFlow::Node mid | + exists(Instruction mid | step(mid, node, config) and flowsFromSource(mid, pragma[only_bind_into](config)) ) @@ -66,12 +65,12 @@ private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration con /** Holds if `node` flows to a sink. */ pragma[nomagic] -private predicate flowsToSink(DataFlow::Node node, MustFlowConfiguration config) { +private predicate flowsToSink(Instruction node, MustFlowConfiguration config) { flowsFromSource(node, pragma[only_bind_into](config)) and ( - config.isSink(node) + config.isSink(node.getAUse()) or - exists(DataFlow::Node mid | + exists(Instruction mid | step(node, mid, config) and flowsToSink(mid, pragma[only_bind_into](config)) ) @@ -198,12 +197,13 @@ private module Cached { } cached - predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - instructionToOperandStep(nodeFrom.asInstruction(), nodeTo.asOperand()) + predicate step(Instruction nodeFrom, Instruction nodeTo) { + exists(Operand mid | + instructionToOperandStep(nodeFrom, mid) and + operandToInstructionStep(mid, nodeTo) + ) or - flowThroughCallable(nodeFrom.asInstruction(), nodeTo.asInstruction()) - or - operandToInstructionStep(nodeFrom.asOperand(), nodeTo.asInstruction()) + flowThroughCallable(nodeFrom, nodeTo) } } @@ -213,12 +213,12 @@ private module Cached { * way around. */ pragma[inline] -private Declaration getEnclosingCallable(DataFlow::Node n) { - pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingCallable() +private IRFunction getEnclosingCallable(Instruction n) { + pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingIRFunction() } /** Holds if `nodeFrom` flows to `nodeTo`. */ -private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) { +private predicate step(Instruction nodeFrom, Instruction nodeTo, MustFlowConfiguration config) { exists(config) and Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and ( @@ -227,37 +227,37 @@ private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowC getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo) ) or - config.isAdditionalFlowStep(nodeFrom, nodeTo) + config.isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo) } private newtype TLocalPathNode = - MkLocalPathNode(DataFlow::Node n, MustFlowConfiguration config) { + MkLocalPathNode(Instruction n, MustFlowConfiguration config) { flowsToSink(n, config) and ( config.isSource(n) or - exists(MustFlowPathNode mid | step(mid.getNode(), n, config)) + exists(MustFlowPathNode mid | step(mid.getInstruction(), n, config)) ) } /** A `Node` that is in a path from a source to a sink. */ class MustFlowPathNode extends TLocalPathNode { - DataFlow::Node n; + Instruction n; MustFlowPathNode() { this = MkLocalPathNode(n, _) } /** Gets the underlying node. */ - DataFlow::Node getNode() { result = n } + Instruction getInstruction() { result = n } /** Gets a textual representation of this node. */ - string toString() { result = n.toString() } + string toString() { result = n.getAst().toString() } /** Gets the location of this element. */ Location getLocation() { result = n.getLocation() } /** Gets a successor node, if any. */ MustFlowPathNode getASuccessor() { - step(this.getNode(), result.getNode(), this.getConfiguration()) + step(this.getInstruction(), result.getInstruction(), this.getConfiguration()) } /** Gets the associated configuration. */ @@ -265,7 +265,7 @@ class MustFlowPathNode extends TLocalPathNode { } private class MustFlowPathSink extends MustFlowPathNode { - MustFlowPathSink() { this.getConfiguration().isSink(this.getNode()) } + MustFlowPathSink() { this.getConfiguration().isSink(this.getInstruction().getAUse()) } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9aa6a529a5b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -915,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -1304,6 +1343,113 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; @@ -1336,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } } @@ -1350,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1362,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll index dde16ab5a2a..e85e0cd92ec 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll @@ -136,6 +136,18 @@ module Consistency { msg = "Local flow step does not preserve enclosing callable." } + query predicate readStepIsLocal(Node n1, Node n2, string msg) { + readStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Read step does not preserve enclosing callable." + } + + query predicate storeStepIsLocal(Node n1, Node n2, string msg) { + storeStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Store step does not preserve enclosing callable." + } + private DataFlowType typeRepr() { result = getNodeType(_) } query predicate compatibleTypesReflexive(DataFlowType t, string msg) { @@ -232,4 +244,25 @@ module Consistency { not callable = viableCallable(call) and not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) } + + query predicate uniqueParameterNodeAtPosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and + msg = "Parameters with overlapping positions." + } + + query predicate uniqueParameterNodePosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and + msg = "Parameter node with multiple positions." + } + + query predicate uniqueContentApprox(Content c, string msg) { + not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and + msg = "Non-unique content approximation." + } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 7f8524a4b44..e068f81f542 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -400,6 +400,13 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves */ predicate allowParameterReturnInSelf(ParameterNode p) { none() } +/** An approximated `Content`. */ +class ContentApprox = Unit; + +/** Gets an approximated value for content `c`. */ +pragma[inline] +ContentApprox getContentApprox(Content c) { any() } + private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { override predicate argHasPostUpdateExclude(ArgumentNode n) { // The rules for whether an IR argument gets a post-update node are too diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll new file mode 100644 index 00000000000..d6a43ed2975 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll @@ -0,0 +1,644 @@ +/** + * INTERNAL: Do not use. + * + * An IR taint tracking library that uses an IR DataFlow configuration to track + * taint from user inputs as defined by `semmle.code.cpp.security.Security`. + */ + +import cpp +import semmle.code.cpp.security.Security +private import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil +private import semmle.code.cpp.ir.dataflow.DataFlow3 +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.ResolveCall +private import semmle.code.cpp.controlflow.IRGuards +private import semmle.code.cpp.models.interfaces.Taint +private import semmle.code.cpp.models.interfaces.DataFlow +private import semmle.code.cpp.ir.dataflow.TaintTracking +private import semmle.code.cpp.ir.dataflow.TaintTracking2 +private import semmle.code.cpp.ir.dataflow.TaintTracking3 +private import semmle.code.cpp.ir.dataflow.internal.ModelUtil + +/** + * A predictable instruction is one where an external user can predict + * the value. For example, a literal in the source code is considered + * predictable. + */ +private predicate predictableInstruction(Instruction instr) { + instr instanceof ConstantInstruction + or + instr instanceof StringConstantInstruction + or + // This could be a conversion on a string literal + predictableInstruction(instr.(UnaryInstruction).getUnary()) +} + +/** + * Functions that we should only allow taint to flow through (to the return + * value) if all but the source argument are 'predictable'. This is done to + * emulate the old security library's implementation rather than due to any + * strong belief that this is the right approach. + * + * Note that the list itself is not very principled; it consists of all the + * functions listed in the old security library's [default] `isPureFunction` + * that have more than one argument, but are not in the old taint tracking + * library's `returnArgument` predicate. + */ +predicate predictableOnlyFlow(string name) { + name = + [ + "strcasestr", "strchnul", "strchr", "strchrnul", "strcmp", "strcspn", "strncmp", "strndup", + "strnlen", "strrchr", "strspn", "strstr", "strtod", "strtof", "strtol", "strtoll", "strtoq", + "strtoul" + ] +} + +private DataFlow::Node getNodeForSource(Expr source) { + isUserInput(source, _) and + result = getNodeForExpr(source) +} + +private DataFlow::Node getNodeForExpr(Expr node) { + result = DataFlow::exprNode(node) + or + // Some of the sources in `isUserInput` are intended to match the value of + // an expression, while others (those modeled below) are intended to match + // the taint that propagates out of an argument, like the `char *` argument + // to `gets`. It's impossible here to tell which is which, but the "access + // to argv" source is definitely not intended to match an output argument, + // and it causes false positives if we let it. + // + // This case goes together with the similar (but not identical) rule in + // `nodeIsBarrierIn`. + result = DataFlow::definitionByReferenceNodeFromArgument(node) and + not argv(node.(VariableAccess).getTarget()) +} + +private class DefaultTaintTrackingCfg extends TaintTracking::Configuration { + DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" } + + override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } + + override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } + + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } + + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } +} + +private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration { + ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" } + + override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } + + override predicate isSink(DataFlow::Node sink) { + sink.asVariable() instanceof GlobalOrNamespaceVariable + } + + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) + or + readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) + } + + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } + + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } +} + +private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration { + FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" } + + override predicate isSource(DataFlow::Node source) { + // This set of sources should be reasonably small, which is good for + // performance since the set of sinks is very large. + exists(ToGlobalVarTaintTrackingCfg otherCfg | otherCfg.hasFlowTo(source)) + } + + override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } + + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + // Additional step for flow out of variables. There is no flow _into_ + // variables in this configuration, so this step only serves to take flow + // out of a variable that's a source. + readsVariable(n2.asInstruction(), n1.asVariable()) + } + + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } + + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } +} + +private predicate readsVariable(LoadInstruction load, Variable var) { + load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var +} + +private predicate writesVariable(StoreInstruction store, Variable var) { + store.getDestinationAddress().(VariableAddressInstruction).getAstVariable() = var +} + +/** + * A variable that has any kind of upper-bound check anywhere in the program. This is + * biased towards being inclusive because there are a lot of valid ways of doing an + * upper bounds checks if we don't consider where it occurs, for example: + * ``` + * if (x < 10) { sink(x); } + * + * if (10 > y) { sink(y); } + * + * if (z > 10) { z = 10; } + * sink(z); + * ``` + */ +// TODO: This coarse overapproximation, ported from the old taint tracking +// library, could be replaced with an actual semantic check that a particular +// variable _access_ is guarded by an upper-bound check. We probably don't want +// to do this right away since it could expose a lot of FPs that were +// previously suppressed by this predicate by coincidence. +private predicate hasUpperBoundsCheck(Variable var) { + exists(RelationalOperation oper, VariableAccess access | + oper.getAnOperand() = access and + access.getTarget() = var and + // Comparing to 0 is not an upper bound check + not oper.getAnOperand().getValue() = "0" + ) +} + +private predicate nodeIsBarrierEqualityCandidate( + DataFlow::Node node, Operand access, Variable checkedVar +) { + readsVariable(node.asInstruction(), checkedVar) and + any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true) +} + +cached +private module Cached { + cached + predicate nodeIsBarrier(DataFlow::Node node) { + exists(Variable checkedVar | + readsVariable(node.asInstruction(), checkedVar) and + hasUpperBoundsCheck(checkedVar) + ) + or + exists(Variable checkedVar, Operand access | + /* + * This node is guarded by a condition that forces the accessed variable + * to equal something else. For example: + * ``` + * x = taintsource() + * if (x == 10) { + * taintsink(x); // not considered tainted + * } + * ``` + */ + + nodeIsBarrierEqualityCandidate(node, access, checkedVar) and + readsVariable(access.getDef(), checkedVar) + ) + } + + cached + predicate nodeIsBarrierIn(DataFlow::Node node) { + // don't use dataflow into taint sources, as this leads to duplicate results. + exists(Expr source | isUserInput(source, _) | + node = DataFlow::exprNode(source) + or + // This case goes together with the similar (but not identical) rule in + // `getNodeForSource`. + node = DataFlow::definitionByReferenceNodeFromArgument(source) + ) + or + // don't use dataflow into binary instructions if both operands are unpredictable + exists(BinaryInstruction iTo | + iTo = node.asInstruction() and + not predictableInstruction(iTo.getLeft()) and + not predictableInstruction(iTo.getRight()) and + // propagate taint from either the pointer or the offset, regardless of predictability + not iTo instanceof PointerArithmeticInstruction + ) + or + // don't use dataflow through calls to pure functions if two or more operands + // are unpredictable + exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo | + iTo = node.asInstruction() and + isPureFunction(iTo.getStaticCallTarget().getName()) and + iFrom1 = iTo.getAnArgument() and + iFrom2 = iTo.getAnArgument() and + not predictableInstruction(iFrom1) and + not predictableInstruction(iFrom2) and + iFrom1 != iFrom2 + ) + } + + cached + Element adjustedSink(DataFlow::Node sink) { + // TODO: is it more appropriate to use asConvertedExpr here and avoid + // `getConversion*`? Or will that cause us to miss some cases where there's + // flow to a conversion (like a `ReferenceDereferenceExpr`) and we want to + // pretend there was flow to the converted `Expr` for the sake of + // compatibility. + sink.asExpr().getConversion*() = result + or + // For compatibility, send flow from arguments to parameters, even for + // functions with no body. + exists(FunctionCall call, int i | + sink.asExpr() = call.getArgument(pragma[only_bind_into](i)) and + result = resolveCall(call).getParameter(pragma[only_bind_into](i)) + ) + or + // For compatibility, send flow into a `Variable` if there is flow to any + // Load or Store of that variable. + exists(CopyInstruction copy | + copy.getSourceValue() = sink.asInstruction() and + ( + readsVariable(copy, result) or + writesVariable(copy, result) + ) and + not hasUpperBoundsCheck(result) + ) + or + // For compatibility, send flow into a `NotExpr` even if it's part of a + // short-circuiting condition and thus might get skipped. + result.(NotExpr).getOperand() = sink.asExpr() + or + // Taint postfix and prefix crement operations when their operand is tainted. + result.(CrementOperation).getAnOperand() = sink.asExpr() + or + // Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted. + result.(AssignOperation).getAnOperand() = sink.asExpr() + or + result = + sink.asOperand() + .(SideEffectOperand) + .getUse() + .(ReadSideEffectInstruction) + .getArgumentDef() + .getUnconvertedResultExpression() + } + + /** + * Step to return value of a modeled function when an input taints the + * dereference of the return value. + */ + cached + predicate additionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + exists(CallInstruction call, Function func, FunctionInput modelIn, FunctionOutput modelOut | + n1.asOperand() = callInput(call, modelIn) and + ( + func.(TaintFunction).hasTaintFlow(modelIn, modelOut) + or + func.(DataFlowFunction).hasDataFlow(modelIn, modelOut) + ) and + call.getStaticCallTarget() = func and + modelOut.isReturnValueDeref() and + call = n2.asInstruction() + ) + } +} + +private import Cached + +/** + * Holds if `tainted` may contain taint from `source`. + * + * A tainted expression is either directly user input, or is + * computed from user input in a way that users can probably + * control the exact output of the computation. + * + * This doesn't include data flow through global variables. + * If you need that you must call `taintedIncludingGlobalVars`. + */ +cached +predicate tainted(Expr source, Element tainted) { + exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink | + cfg.hasFlow(getNodeForSource(source), sink) and + tainted = adjustedSink(sink) + ) +} + +/** + * Holds if `tainted` may contain taint from `source`, where the taint passed + * through a global variable named `globalVar`. + * + * A tainted expression is either directly user input, or is + * computed from user input in a way that users can probably + * control the exact output of the computation. + * + * This version gives the same results as tainted but also includes + * data flow through global variables. + * + * The parameter `globalVar` is the qualified name of the last global variable + * used to move the value from source to tainted. If the taint did not pass + * through a global variable, then `globalVar = ""`. + */ +cached +predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) { + tainted(source, tainted) and + globalVar = "" + or + exists( + ToGlobalVarTaintTrackingCfg toCfg, FromGlobalVarTaintTrackingCfg fromCfg, + DataFlow::VariableNode variableNode, GlobalOrNamespaceVariable global, DataFlow::Node sink + | + global = variableNode.getVariable() and + toCfg.hasFlow(getNodeForSource(source), variableNode) and + fromCfg.hasFlow(variableNode, sink) and + tainted = adjustedSink(sink) and + global = globalVarFromId(globalVar) + ) +} + +/** + * Gets the global variable whose qualified name is `id`. Use this predicate + * together with `taintedIncludingGlobalVars`. Example: + * + * ``` + * exists(string varName | + * taintedIncludingGlobalVars(source, tainted, varName) and + * var = globalVarFromId(varName) + * ) + * ``` + */ +GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() } + +/** + * Provides definitions for augmenting source/sink pairs with data-flow paths + * between them. From a `@kind path-problem` query, import this module in the + * global scope, extend `TaintTrackingConfiguration`, and use `taintedWithPath` + * in place of `tainted`. + * + * Importing this module will also import the query predicates that contain the + * taint paths. + */ +module TaintedWithPath { + private newtype TSingleton = MkSingleton() + + /** + * A taint-tracking configuration that matches sources and sinks in the same + * way as the `tainted` predicate. + * + * Override `isSink` and `taintThroughGlobals` as needed, but do not provide + * a characteristic predicate. + */ + class TaintTrackingConfiguration extends TSingleton { + /** Override this to specify which elements are sources in this configuration. */ + predicate isSource(Expr source) { exists(getNodeForSource(source)) } + + /** Override this to specify which elements are sinks in this configuration. */ + abstract predicate isSink(Element e); + + /** Override this to specify which expressions are barriers in this configuration. */ + predicate isBarrier(Expr e) { nodeIsBarrier(getNodeForExpr(e)) } + + /** + * Override this predicate to `any()` to allow taint to flow through global + * variables. + */ + predicate taintThroughGlobals() { none() } + + /** Gets a textual representation of this element. */ + string toString() { result = "TaintTrackingConfiguration" } + } + + private class AdjustedConfiguration extends TaintTracking3::Configuration { + AdjustedConfiguration() { this = "AdjustedConfiguration" } + + override predicate isSource(DataFlow::Node source) { + exists(TaintTrackingConfiguration cfg, Expr e | + cfg.isSource(e) and source = getNodeForExpr(e) + ) + } + + override predicate isSink(DataFlow::Node sink) { + exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink))) + } + + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + // Steps into and out of global variables + exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() | + writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) + or + readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) + ) + or + additionalTaintStep(n1, n2) + } + + override predicate isSanitizer(DataFlow::Node node) { + exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e)) + } + + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } + } + + /* + * A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the + * inverse of) `adjustedSink`. For example, an `Expr` maps to all its + * conversions, and a `Variable` maps to all loads and stores from it. Because + * the path node is part of the tuple that constitutes the alert, this leads + * to duplicate alerts. + * + * To avoid showing duplicates, we edit the graph to replace the final node + * coming from the data-flow library with a node that matches exactly the + * `Element` sink that's requested. + * + * The same is done for sources. + */ + + private newtype TPathNode = + TWrapPathNode(DataFlow3::PathNode n) or + // There's a single newtype constructor for both sources and sinks since + // that makes it easiest to deal with the case where source = sink. + TEndpointPathNode(Element e) { + exists(AdjustedConfiguration cfg, DataFlow3::Node sourceNode, DataFlow3::Node sinkNode | + cfg.hasFlow(sourceNode, sinkNode) + | + sourceNode = getNodeForExpr(e) and + exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e)) + or + e = adjustedSink(sinkNode) and + exists(TaintTrackingConfiguration ttCfg | ttCfg.isSink(e)) + ) + } + + /** An opaque type used for the nodes of a data-flow path. */ + class PathNode extends TPathNode { + /** Gets a textual representation of this element. */ + string toString() { none() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + none() + } + } + + /** + * INTERNAL: Do not use. + */ + module Private { + /** Gets a predecessor `PathNode` of `pathNode`, if any. */ + PathNode getAPredecessor(PathNode pathNode) { edges(result, pathNode) } + + /** Gets the element that `pathNode` wraps, if any. */ + Element getElementFromPathNode(PathNode pathNode) { + exists(DataFlow::Node node | node = pathNode.(WrapPathNode).inner().getNode() | + result = node.asInstruction().getAst() + or + result = node.asOperand().getDef().getAst() + ) + or + result = pathNode.(EndpointPathNode).inner() + } + } + + private class WrapPathNode extends PathNode, TWrapPathNode { + DataFlow3::PathNode inner() { this = TWrapPathNode(result) } + + override string toString() { result = this.inner().toString() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.inner().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + } + + private class EndpointPathNode extends PathNode, TEndpointPathNode { + Expr inner() { this = TEndpointPathNode(result) } + + override string toString() { result = this.inner().toString() } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.inner() + .getLocation() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + } + + /** A PathNode whose `Element` is a source. It may also be a sink. */ + private class InitialPathNode extends EndpointPathNode { + InitialPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSource(this.inner())) } + } + + /** A PathNode whose `Element` is a sink. It may also be a source. */ + private class FinalPathNode extends EndpointPathNode { + FinalPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSink(this.inner())) } + } + + /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ + query predicate edges(PathNode a, PathNode b) { + DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), b.(WrapPathNode).inner()) + or + // To avoid showing trivial-looking steps, we _replace_ the last node instead + // of adding an edge out of it. + exists(WrapPathNode sinkNode | + DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), sinkNode.inner()) and + b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + or + // Same for the first node + exists(WrapPathNode sourceNode | + DataFlow3::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and + sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) + ) + or + // Finally, handle the case where the path goes directly from a source to a + // sink, meaning that they both need to be translated. + exists(WrapPathNode sinkNode, WrapPathNode sourceNode | + DataFlow3::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and + sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) and + b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + } + + /** + * Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow + * from `par` to `ret` within it, in the graph of data flow path explanations. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) + or + // To avoid showing trivial-looking steps, we _replace_ the last node instead + // of adding an edge out of it. + exists(WrapPathNode sinkNode | + DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), sinkNode.inner()) and + out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + or + // Same for the first node + exists(WrapPathNode sourceNode | + DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and + sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) + ) + or + // Finally, handle the case where the path goes directly from a source to a + // sink, meaning that they both need to be translated. + exists(WrapPathNode sinkNode, WrapPathNode sourceNode | + DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), sinkNode.inner()) and + sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and + out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + } + + /** Holds if `n` is a node in the graph of data flow path explanations. */ + query predicate nodes(PathNode n, string key, string val) { + key = "semmle.label" and val = n.toString() + } + + /** + * Holds if `tainted` may contain taint from `source`, where `sourceNode` and + * `sinkNode` are the corresponding `PathNode`s that can be used in a query + * to provide path explanations. Extend `TaintTrackingConfiguration` to use + * this predicate. + * + * A tainted expression is either directly user input, or is computed from + * user input in a way that users can probably control the exact output of + * the computation. + */ + predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) { + exists(AdjustedConfiguration cfg, DataFlow3::Node flowSource, DataFlow3::Node flowSink | + source = sourceNode.(InitialPathNode).inner() and + flowSource = getNodeForExpr(source) and + cfg.hasFlow(flowSource, flowSink) and + tainted = adjustedSink(flowSink) and + tainted = sinkNode.(FinalPathNode).inner() + ) + } + + private predicate isGlobalVariablePathNode(WrapPathNode n) { + n.inner().getNode().asVariable() instanceof GlobalOrNamespaceVariable + } + + private predicate edgesWithoutGlobals(PathNode a, PathNode b) { + edges(a, b) and + not isGlobalVariablePathNode(a) and + not isGlobalVariablePathNode(b) + } + + /** + * Holds if `tainted` can be reached from a taint source without passing + * through a global variable. + */ + predicate taintedWithoutGlobals(Element tainted) { + exists(AdjustedConfiguration cfg, PathNode sourceNode, FinalPathNode sinkNode | + cfg.isSource(sourceNode.(WrapPathNode).inner().getNode()) and + edgesWithoutGlobals+(sourceNode, sinkNode) and + tainted = sinkNode.inner() + ) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 3eed4341cce..1318fd37b7f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -27,7 +27,7 @@ private import implementations.StdString private import implementations.Swap private import implementations.GetDelim private import implementations.SmartPointer -private import implementations.Sscanf +private import implementations.Scanf private import implementations.Send private import implementations.Recv private import implementations.Accept diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Fread.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Fread.qll index df2d92fbc4f..39733167b81 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Fread.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Fread.qll @@ -15,6 +15,6 @@ private class Fread extends AliasFunction, RemoteFlowSourceFunction { override predicate hasRemoteFlowSource(FunctionOutput output, string description) { output.isParameterDeref(0) and - description = "String read by " + this.getName() + description = "string read by " + this.getName() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll index 67950b6e135..6cf642bd4cb 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll @@ -36,6 +36,6 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF override predicate hasRemoteFlowSource(FunctionOutput output, string description) { output.isParameterDeref(0) and - description = "String read by " + this.getName() + description = "string read by " + this.getName() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Getenv.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Getenv.qll index 87e191241d2..256b1a86ed5 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Getenv.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Getenv.qll @@ -1,15 +1,19 @@ /** - * Provides an implementation class modeling the POSIX function `getenv`. + * Provides an implementation class modeling the POSIX function `getenv` and + * various similar functions. */ import cpp import semmle.code.cpp.models.interfaces.FlowSource /** - * The POSIX function `getenv`. + * The POSIX function `getenv`, the GNU function `secure_getenv`, and the + * Windows function `_wgetenv`. */ class Getenv extends LocalFlowSourceFunction { - Getenv() { this.hasGlobalOrStdOrBslName("getenv") } + Getenv() { + this.hasGlobalOrStdOrBslName("getenv") or this.hasGlobalName(["secure_getenv", "_wgetenv"]) + } override predicate hasLocalFlowSource(FunctionOutput output, string description) { ( diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll index 67b9307bbe1..b89eb2c1f14 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll @@ -49,10 +49,10 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti override predicate hasRemoteFlowSource(FunctionOutput output, string description) { output.isParameterDeref(0) and - description = "String read by " + this.getName() + description = "string read by " + this.getName() or output.isReturnValue() and - description = "String read by " + this.getName() + description = "string read by " + this.getName() } override predicate hasArrayWithVariableSize(int bufParam, int countParam) { @@ -98,10 +98,10 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio override predicate hasLocalFlowSource(FunctionOutput output, string description) { output.isParameterDeref(0) and - description = "String read by " + this.getName() + description = "string read by " + this.getName() or output.isReturnValue() and - description = "String read by " + this.getName() + description = "string read by " + this.getName() } override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 0 } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll index 397dca69fed..c0c4537b746 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll @@ -1,9 +1,10 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.FlowSource private class InetNtoa extends TaintFunction { - InetNtoa() { hasGlobalName("inet_ntoa") } + InetNtoa() { this.hasGlobalName("inet_ntoa") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and @@ -12,7 +13,7 @@ private class InetNtoa extends TaintFunction { } private class InetAton extends TaintFunction, ArrayFunction { - InetAton() { hasGlobalName("inet_aton") } + InetAton() { this.hasGlobalName("inet_aton") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(0) and @@ -32,7 +33,7 @@ private class InetAton extends TaintFunction, ArrayFunction { } private class InetAddr extends TaintFunction, ArrayFunction, AliasFunction { - InetAddr() { hasGlobalName("inet_addr") } + InetAddr() { this.hasGlobalName("inet_addr") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(0) and @@ -51,7 +52,7 @@ private class InetAddr extends TaintFunction, ArrayFunction, AliasFunction { } private class InetNetwork extends TaintFunction, ArrayFunction { - InetNetwork() { hasGlobalName("inet_network") } + InetNetwork() { this.hasGlobalName("inet_network") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(0) and @@ -64,7 +65,7 @@ private class InetNetwork extends TaintFunction, ArrayFunction { } private class InetMakeaddr extends TaintFunction { - InetMakeaddr() { hasGlobalName("inet_makeaddr") } + InetMakeaddr() { this.hasGlobalName("inet_makeaddr") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { ( @@ -76,7 +77,7 @@ private class InetMakeaddr extends TaintFunction { } private class InetLnaof extends TaintFunction { - InetLnaof() { hasGlobalName("inet_lnaof") } + InetLnaof() { this.hasGlobalName("inet_lnaof") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and @@ -85,7 +86,7 @@ private class InetLnaof extends TaintFunction { } private class InetNetof extends TaintFunction { - InetNetof() { hasGlobalName("inet_netof") } + InetNetof() { this.hasGlobalName("inet_netof") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and @@ -94,7 +95,7 @@ private class InetNetof extends TaintFunction { } private class InetPton extends TaintFunction, ArrayFunction { - InetPton() { hasGlobalName("inet_pton") } + InetPton() { this.hasGlobalName("inet_pton") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { ( @@ -114,7 +115,7 @@ private class InetPton extends TaintFunction, ArrayFunction { } private class Gethostbyname extends TaintFunction, ArrayFunction { - Gethostbyname() { hasGlobalName("gethostbyname") } + Gethostbyname() { this.hasGlobalName("gethostbyname") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(0) and @@ -127,7 +128,7 @@ private class Gethostbyname extends TaintFunction, ArrayFunction { } private class Gethostbyaddr extends TaintFunction, ArrayFunction { - Gethostbyaddr() { hasGlobalName("gethostbyaddr") } + Gethostbyaddr() { this.hasGlobalName("gethostbyaddr") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { ( @@ -142,3 +143,21 @@ private class Gethostbyaddr extends TaintFunction, ArrayFunction { override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 } } + +private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSourceFunction { + Getaddrinfo() { this.hasGlobalName("getaddrinfo") } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isParameterDeref([0 .. 2]) and + output.isParameterDeref(3) + } + + override predicate hasArrayInput(int bufParam) { bufParam in [0, 1] } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] } + + override predicate hasRemoteFlowSource(FunctionOutput output, string description) { + output.isParameterDeref(3) and + description = "address returned by " + this.getName() + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 2fa9803d053..599b2c47e22 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -31,7 +31,17 @@ private class IteratorTraits extends Class { * `std::iterator_traits` instantiation for it. */ private class IteratorByTraits extends Iterator { - IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) } + IteratorTraits trait; + + IteratorByTraits() { trait.getIteratorType() = this } + + override Type getValueType() { + exists(TypedefType t | + trait.getAMember() = t and + t.getName() = "value_type" and + result = t.getUnderlyingType() + ) + } } /** @@ -42,20 +52,27 @@ private class IteratorByTraits extends Iterator { */ private class IteratorByPointer extends Iterator instanceof PointerType { IteratorByPointer() { not this instanceof IteratorByTraits } + + override Type getValueType() { result = super.getBaseType() } } /** * A type which has the typedefs expected for an iterator. */ private class IteratorByTypedefs extends Iterator, Class { + TypedefType valueType; + IteratorByTypedefs() { this.getAMember().(TypedefType).hasName("difference_type") and - this.getAMember().(TypedefType).hasName("value_type") and + valueType = this.getAMember() and + valueType.hasName("value_type") and this.getAMember().(TypedefType).hasName("pointer") and this.getAMember().(TypedefType).hasName("reference") and this.getAMember().(TypedefType).hasName("iterator_category") and not this.hasQualifiedName(["std", "bsl"], "iterator_traits") } + + override Type getValueType() { result = valueType.getUnderlyingType() } } /** @@ -63,6 +80,8 @@ private class IteratorByTypedefs extends Iterator, Class { */ private class StdIterator extends Iterator, Class { StdIterator() { this.hasQualifiedName(["std", "bsl"], "iterator") } + + override Type getValueType() { result = this.getTemplateArgument(1).(Type).getUnderlyingType() } } /** @@ -166,12 +185,15 @@ private class IteratorSubOperator extends Operator, TaintFunction { /** * A non-member `operator+=` or `operator-=` function for an iterator type. */ -private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, TaintFunction { +class IteratorAssignArithmeticOperator extends Operator { IteratorAssignArithmeticOperator() { this.hasName(["operator+=", "operator-="]) and exists(getIteratorArgumentInput(this, 0)) } +} +private class IteratorAssignArithmeticOperatorModel extends IteratorAssignArithmeticOperator, + DataFlowFunction, TaintFunction { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and output.isReturnValue() @@ -210,11 +232,14 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc /** * An `operator++` or `operator--` member function for an iterator type. */ -private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunction, TaintFunction { +class IteratorCrementMemberOperator extends MemberFunction { IteratorCrementMemberOperator() { this.getClassAndName(["operator++", "operator--"]) instanceof Iterator } +} +private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator, + DataFlowFunction, TaintFunction { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isQualifierAddress() and output.isReturnValue() diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll index 0551185ba14..6a4dd524b86 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll @@ -83,7 +83,7 @@ private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction, or this.hasGlobalName("recvfrom") and output.isParameterDeref([4, 5]) ) and - description = "Buffer read by " + this.getName() + description = "buffer read by " + this.getName() } override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll similarity index 57% rename from cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll rename to cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll index 42166ae9baa..9a9e02611f8 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll @@ -1,6 +1,6 @@ /** - * Provides implementation classes modeling `sscanf`, `fscanf` and various similar - * functions. See `semmle.code.cpp.models.Models` for usage information. + * Provides implementation classes modeling the `scanf` family of functions. + * See `semmle.code.cpp.models.Models` for usage information. */ import semmle.code.cpp.Function @@ -9,18 +9,15 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.FlowSource /** - * The standard function `sscanf`, `fscanf` and its assorted variants + * The `scanf` family of functions. */ -private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction { - SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf } - +abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction, AliasFunction, + SideEffectFunction { override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = this.(ScanfFunction).getFormatParameterIndex() - or - not this instanceof Fscanf and - bufParam = this.(ScanfFunction).getInputParameterIndex() } override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) } @@ -36,7 +33,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S ) } - private int getArgsStartPosition() { result = this.getNumberOfParameters() } + int getArgsStartPosition() { result = this.getNumberOfParameters() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and @@ -70,3 +67,36 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S ] } } + +/** + * The standard function `scanf` and its assorted variants + */ +private class ScanfModel extends ScanfFunctionModel, LocalFlowSourceFunction instanceof Scanf { + override predicate hasLocalFlowSource(FunctionOutput output, string description) { + output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and + description = "value read by " + this.getName() + } +} + +/** + * The standard function `fscanf` and its assorted variants + */ +private class FscanfModel extends ScanfFunctionModel, RemoteFlowSourceFunction instanceof Fscanf { + override predicate hasRemoteFlowSource(FunctionOutput output, string description) { + output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and + description = "value read by " + this.getName() + } +} + +/** + * The standard function `sscanf` and its assorted variants + */ +private class SscanfModel extends ScanfFunctionModel { + SscanfModel() { this instanceof Sscanf or this instanceof Snscanf } + + override predicate hasArrayWithNullTerminator(int bufParam) { + super.hasArrayWithNullTerminator(bufParam) + or + bufParam = this.(ScanfFunction).getInputParameterIndex() + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll index d871bad68af..16047b21183 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll @@ -58,7 +58,7 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 } override predicate hasRemoteFlowSink(FunctionInput input, string description) { - input.isParameterDeref(1) and description = "Buffer sent by " + this.getName() + input.isParameterDeref(1) and description = "buffer sent by " + this.getName() } override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll index 8c531891bcd..9d74f4ac051 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll @@ -5,38 +5,53 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Iterator +/** + * A sequence container template class (for example, `std::vector`) from the + * standard library. + */ +abstract class StdSequenceContainer extends Class { + Type getElementType() { result = this.getTemplateArgument(0) } +} + /** * The `std::array` template class. */ -private class Array extends Class { +private class Array extends StdSequenceContainer { Array() { this.hasQualifiedName(["std", "bsl"], "array") } } +/** + * The `std::string` template class. + */ +private class String extends StdSequenceContainer { + String() { this.hasQualifiedName(["std", "bsl"], "basic_string") } +} + /** * The `std::deque` template class. */ -private class Deque extends Class { +private class Deque extends StdSequenceContainer { Deque() { this.hasQualifiedName(["std", "bsl"], "deque") } } /** * The `std::forward_list` template class. */ -private class ForwardList extends Class { +private class ForwardList extends StdSequenceContainer { ForwardList() { this.hasQualifiedName(["std", "bsl"], "forward_list") } } /** * The `std::list` template class. */ -private class List extends Class { +private class List extends StdSequenceContainer { List() { this.hasQualifiedName(["std", "bsl"], "list") } } /** * The `std::vector` template class. */ -private class Vector extends Class { +private class Vector extends StdSequenceContainer { Vector() { this.hasQualifiedName(["std", "bsl"], "vector") } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll index 3d2eda59799..b1534a585a1 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -16,21 +16,32 @@ private class StdBasicString extends ClassTemplateInstantiation { } /** - * Additional model for `std::string` constructors that reference the character - * type of the container, or an iterator. For example construction from - * iterators: - * ``` - * std::string b(a.begin(), a.end()); - * ``` + * The `std::basic_string::iterator` declaration. + * + * Intuitively, this class shouldn't be necessary as it's already captured + * by the `StdIterator` class. However, this class ensures that the typedef inside the + * body of the `std::string` class is also seen as an iterator. + * + * Eventually, we should be consistent about which of the following should be recognized as iterators: + * 1. The typedef type. + * 2. The template class of the resolved type. + * 3. Any instantiation of the resolved type. */ -private class StdStringConstructor extends Constructor, TaintFunction { - StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString } +private class StdBasicStringIterator extends Iterator, Type { + StdBasicStringIterator() { + this.getEnclosingElement() instanceof StdBasicString and this.hasName("iterator") + } +} +/** + * A `std::string` function for which taint should be propagated. + */ +abstract private class StdStringTaintFunction extends TaintFunction { /** * Gets the index of a parameter to this function that is a string (or * character). */ - int getAStringParameterIndex() { + final int getAStringParameterIndex() { exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() | // e.g. `std::basic_string::CharT *` paramType instanceof PointerType @@ -41,15 +52,28 @@ private class StdStringConstructor extends Constructor, TaintFunction { this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType() or // i.e. `std::basic_string::CharT` - this.getParameter(result).getUnspecifiedType() = - this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() + paramType = this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() ) } /** * Gets the index of a parameter to this function that is an iterator. */ - int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator } + final int getAnIteratorParameterIndex() { + this.getParameter(result).getType() instanceof Iterator + } +} + +/** + * Additional model for `std::string` constructors that reference the character + * type of the container, or an iterator. For example construction from + * iterators: + * ``` + * std::string b(a.begin(), a.end()); + * ``` + */ +private class StdStringConstructor extends Constructor, StdStringTaintFunction { + StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from any parameter of the value type to the returned object @@ -68,7 +92,7 @@ private class StdStringConstructor extends Constructor, TaintFunction { /** * The `std::string` function `c_str`. */ -private class StdStringCStr extends TaintFunction { +private class StdStringCStr extends StdStringTaintFunction { StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -81,7 +105,7 @@ private class StdStringCStr extends TaintFunction { /** * The `std::string` function `data`. */ -private class StdStringData extends TaintFunction { +private class StdStringData extends StdStringTaintFunction { StdStringData() { this.getClassAndName("data") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -99,7 +123,7 @@ private class StdStringData extends TaintFunction { /** * The `std::string` function `push_back`. */ -private class StdStringPush extends TaintFunction { +private class StdStringPush extends StdStringTaintFunction { StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -112,7 +136,7 @@ private class StdStringPush extends TaintFunction { /** * The `std::string` functions `front` and `back`. */ -private class StdStringFrontBack extends TaintFunction { +private class StdStringFrontBack extends StdStringTaintFunction { StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -125,7 +149,7 @@ private class StdStringFrontBack extends TaintFunction { /** * The (non-member) `std::string` function `operator+`. */ -private class StdStringPlus extends TaintFunction { +private class StdStringPlus extends StdStringTaintFunction { StdStringPlus() { this.hasQualifiedName(["std", "bsl"], "operator+") and this.getUnspecifiedType() instanceof StdBasicString @@ -142,31 +166,15 @@ private class StdStringPlus extends TaintFunction { } /** - * The `std::string` functions `operator+=`, `append`, `insert` and - * `replace`. All of these functions combine the existing string - * with a new string (or character) from one of the arguments. + * The `std::string` functions `operator+=`, `append` and `replace`. + * All of these functions combine the existing string with a new + * string (or character) from one of the arguments. */ -private class StdStringAppend extends TaintFunction { +private class StdStringAppend extends StdStringTaintFunction { StdStringAppend() { - this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString + this.getClassAndName(["operator+=", "append", "replace"]) instanceof StdBasicString } - /** - * Gets the index of a parameter to this function that is a string (or - * character). - */ - int getAStringParameterIndex() { - this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *` - this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &` - this.getParameter(result).getUnspecifiedType() = - this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT` - } - - /** - * Gets the index of a parameter to this function that is an iterator. - */ - int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator } - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from string and parameter to string (qualifier) and return value ( @@ -186,28 +194,44 @@ private class StdStringAppend extends TaintFunction { } } +/** + * The `std::string` function `insert`. + */ +private class StdStringInsert extends StdStringTaintFunction { + StdStringInsert() { this.getClassAndName("insert") instanceof StdBasicString } + + /** + * Holds if the return type is an iterator. + */ + predicate hasIteratorReturnValue() { this.getType() instanceof Iterator } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + // flow from string and parameter to string (qualifier) and return value + ( + input.isQualifierObject() or + input.isParameterDeref(this.getAStringParameterIndex()) or + input.isParameter(this.getAnIteratorParameterIndex()) + ) and + ( + output.isQualifierObject() + or + if this.hasIteratorReturnValue() then output.isReturnValue() else output.isReturnValueDeref() + ) + or + // reverse flow from returned reference to the qualifier (for writes to + // the result) + not this.hasIteratorReturnValue() and + input.isReturnValueDeref() and + output.isQualifierObject() + } +} + /** * The standard function `std::string.assign`. */ -private class StdStringAssign extends TaintFunction { +private class StdStringAssign extends StdStringTaintFunction { StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString } - /** - * Gets the index of a parameter to this function that is a string (or - * character). - */ - int getAStringParameterIndex() { - this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *` - this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &` - this.getParameter(result).getUnspecifiedType() = - this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT` - } - - /** - * Gets the index of a parameter to this function that is an iterator. - */ - int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator } - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from parameter to string itself (qualifier) and return value ( @@ -229,7 +253,7 @@ private class StdStringAssign extends TaintFunction { /** * The standard function `std::string.copy`. */ -private class StdStringCopy extends TaintFunction { +private class StdStringCopy extends StdStringTaintFunction { StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -242,7 +266,7 @@ private class StdStringCopy extends TaintFunction { /** * The standard function `std::string.substr`. */ -private class StdStringSubstr extends TaintFunction { +private class StdStringSubstr extends StdStringTaintFunction { StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -255,7 +279,7 @@ private class StdStringSubstr extends TaintFunction { /** * The `std::string` functions `at` and `operator[]`. */ -private class StdStringAt extends TaintFunction { +private class StdStringAt extends StdStringTaintFunction { StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Allocation.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Allocation.qll index 00281f0f756..38a3ce235fb 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Allocation.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Allocation.qll @@ -11,38 +11,6 @@ import semmle.code.cpp.Function import semmle.code.cpp.models.Models -/** - * An allocation function such as `malloc`. - */ -abstract class AllocationFunction extends Function { - /** - * Gets the index of the argument for the allocation size, if any. The actual - * allocation size is the value of this argument multiplied by the result of - * `getSizeMult()`, in bytes. - */ - int getSizeArg() { none() } - - /** - * Gets the index of an argument that multiplies the allocation size given by - * `getSizeArg`, if any. - */ - int getSizeMult() { none() } - - /** - * Gets the index of the input pointer argument to be reallocated, if this - * is a `realloc` function. - */ - int getReallocPtrArg() { none() } - - /** - * Whether or not this allocation requires a corresponding deallocation of - * some sort (most do, but `alloca` for example does not). If it is unclear, - * we default to no (for example a placement `new` allocation may or may not - * require a corresponding `delete`). - */ - predicate requiresDealloc() { any() } -} - /** * An allocation expression such as call to `malloc` or a `new` expression. */ @@ -86,6 +54,41 @@ abstract class AllocationExpr extends Expr { predicate requiresDealloc() { any() } } +/** + * An allocation function such as `malloc`. + * + * Note: `AllocationExpr` includes calls to allocation functions, so prefer + * to use that class unless you specifically need to reason about functions. + */ +abstract class AllocationFunction extends Function { + /** + * Gets the index of the argument for the allocation size, if any. The actual + * allocation size is the value of this argument multiplied by the result of + * `getSizeMult()`, in bytes. + */ + int getSizeArg() { none() } + + /** + * Gets the index of an argument that multiplies the allocation size given by + * `getSizeArg`, if any. + */ + int getSizeMult() { none() } + + /** + * Gets the index of the input pointer argument to be reallocated, if this + * is a `realloc` function. + */ + int getReallocPtrArg() { none() } + + /** + * Whether or not this allocation requires a corresponding deallocation of + * some sort (most do, but `alloca` for example does not). If it is unclear, + * we default to no (for example a placement `new` allocation may or may not + * require a corresponding `delete`). + */ + predicate requiresDealloc() { any() } +} + /** * An `operator new` or `operator new[]` function that may be associated with * `new` or `new[]` expressions. Note that `new` and `new[]` are not function diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Deallocation.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Deallocation.qll index 9c74102e99c..569caebe36f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Deallocation.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Deallocation.qll @@ -11,16 +11,6 @@ import semmle.code.cpp.Function import semmle.code.cpp.models.Models -/** - * A deallocation function such as `free`. - */ -abstract class DeallocationFunction extends Function { - /** - * Gets the index of the argument that is freed by this function. - */ - int getFreedArg() { none() } -} - /** * An deallocation expression such as call to `free` or a `delete` expression. */ @@ -31,6 +21,19 @@ abstract class DeallocationExpr extends Expr { Expr getFreedExpr() { none() } } +/** + * A deallocation function such as `free`. + * + * Note: `DeallocationExpr` includes calls to deallocation functions, so prefer + * to use that class unless you specifically need to reason about functions. + */ +abstract class DeallocationFunction extends Function { + /** + * Gets the index of the argument that is freed by this function. + */ + int getFreedArg() { none() } +} + /** * An `operator delete` or `operator delete[]` function that may be associated * with `delete` or `delete[]` expressions. Note that `delete` and `delete[]` diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll index 9a260a33255..d5d2b6ffe81 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Iterator.qll @@ -29,5 +29,17 @@ abstract class GetIteratorFunction extends Function { /** * A type which can be used as an iterator. + * + * Note: Do _not_ `extend` when inheriting from this class in queries. Always use `instanceof`: + * ``` + * class MyIterator instanceof Iterator { ... } + * ``` */ -abstract class Iterator extends Type { } +abstract class Iterator extends Type { + /** + * Gets the value type of this iterator, if any. + * + * For example, the value type of a `std::vector::iterator` is `int`. + */ + Type getValueType() { none() } +} diff --git a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll index d2c90a38075..8bc059da506 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll @@ -89,9 +89,9 @@ private class LocalParameterSource extends LocalFlowSource { private class ArgvSource extends LocalFlowSource { ArgvSource() { - exists(Parameter argv | - argv.hasName("argv") and - argv.getFunction().hasGlobalName("main") and + exists(Function main, Parameter argv | + main.hasGlobalName("main") and + main.getParameter(1) = argv and this.asExpr() = argv.getAnAccess() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll index 5b8f221f73a..49ef4137aa1 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/TaintTracking.qll @@ -1,4 +1,4 @@ -/* +/** * Support for tracking tainted data through the program. This is an alias for * `semmle.code.cpp.ir.dataflow.DefaultTaintTracking` provided for backwards * compatibility. diff --git a/cpp/ql/lib/semmle/code/cpp/security/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/security/TaintTrackingImpl.qll index 532cf53e2d4..4d64edc2670 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/TaintTrackingImpl.qll @@ -121,7 +121,9 @@ private predicate moveToDependingOnSide(Expr src, Expr dest) { * (this is done to avoid false positives). Because of this we need to track if the tainted element came from an argument * or not, and for that we use destFromArg */ -private predicate betweenFunctionsValueMoveTo(Element src, Element dest, boolean destFromArg) { +deprecated private predicate betweenFunctionsValueMoveTo( + Element src, Element dest, boolean destFromArg +) { not unreachable(src) and not unreachable(dest) and ( @@ -162,13 +164,13 @@ private predicate betweenFunctionsValueMoveTo(Element src, Element dest, boolean // predicate folding for proper join-order // bad magic: pushes down predicate that ruins join-order pragma[nomagic] -private predicate resolveCallWithParam(Call call, Function called, int i, Parameter p) { +deprecated private predicate resolveCallWithParam(Call call, Function called, int i, Parameter p) { called = resolveCall(call) and p = called.getParameter(i) } /** A variable for which flow through is allowed. */ -library class FlowVariable extends Variable { +deprecated library class FlowVariable extends Variable { FlowVariable() { ( this instanceof LocalScopeVariable or @@ -179,11 +181,11 @@ library class FlowVariable extends Variable { } /** A local scope variable for which flow through is allowed. */ -library class FlowLocalScopeVariable extends Variable { +deprecated library class FlowLocalScopeVariable extends Variable { FlowLocalScopeVariable() { this instanceof LocalScopeVariable } } -private predicate insideFunctionValueMoveTo(Element src, Element dest) { +deprecated private predicate insideFunctionValueMoveTo(Element src, Element dest) { not unreachable(src) and not unreachable(dest) and ( @@ -324,7 +326,7 @@ private predicate unionAccess(Variable v, Field f, FieldAccess a) { a.getQualifier() = v.getAnAccess() } -GlobalOrNamespaceVariable globalVarFromId(string id) { +deprecated GlobalOrNamespaceVariable globalVarFromId(string id) { if result instanceof NamespaceVariable then id = result.getNamespace() + "::" + result.getName() else id = result.getName() @@ -353,7 +355,7 @@ private predicate hasUpperBoundsCheck(Variable var) { } cached -private predicate taintedWithArgsAndGlobalVars( +deprecated private predicate taintedWithArgsAndGlobalVars( Element src, Element dest, boolean destFromArg, string globalVar ) { isUserInput(src, _) and @@ -395,7 +397,7 @@ private predicate taintedWithArgsAndGlobalVars( * This doesn't include data flow through global variables. * If you need that you must call taintedIncludingGlobalVars. */ -predicate tainted(Expr source, Element tainted) { +deprecated predicate tainted(Expr source, Element tainted) { taintedWithArgsAndGlobalVars(source, tainted, _, "") } @@ -410,7 +412,7 @@ predicate tainted(Expr source, Element tainted) { * The parameter `globalVar` is the name of the last global variable used to move the * value from source to tainted. */ -predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) { +deprecated predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) { taintedWithArgsAndGlobalVars(source, tainted, _, globalVar) } @@ -541,14 +543,14 @@ private predicate returnArgument(Function f, int sourceArg) { * targets a virtual method, simple data flow analysis is performed * in order to identify target(s). */ -Function resolveCall(Call call) { +deprecated Function resolveCall(Call call) { result = call.getTarget() or result = call.(DataSensitiveCallExpr).resolve() } /** A data sensitive call expression. */ -abstract library class DataSensitiveCallExpr extends Expr { +abstract deprecated library class DataSensitiveCallExpr extends Expr { DataSensitiveCallExpr() { not unreachable(this) } abstract Expr getSrc(); @@ -579,7 +581,7 @@ abstract library class DataSensitiveCallExpr extends Expr { } /** Call through a function pointer. */ -library class DataSensitiveExprCall extends DataSensitiveCallExpr, ExprCall { +deprecated library class DataSensitiveExprCall extends DataSensitiveCallExpr, ExprCall { override Expr getSrc() { result = getExpr() } override Function resolve() { @@ -588,7 +590,8 @@ library class DataSensitiveExprCall extends DataSensitiveCallExpr, ExprCall { } /** Call to a virtual function. */ -library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr, FunctionCall { +deprecated library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr, + FunctionCall { DataSensitiveOverriddenFunctionCall() { exists(getTarget().(VirtualFunction).getAnOverridingFunction()) } diff --git a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll index 7dd55dbfde3..10e3d3ba1c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/valuenumbering/GlobalValueNumberingImpl.qll @@ -1,4 +1,8 @@ /** + * DEPRECATED: This library has been replaced with a newer version which + * provides better performance and precision. Use + * `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead. + * * Provides an implementation of Global Value Numbering. * See https://en.wikipedia.org/wiki/Global_value_numbering * @@ -221,7 +225,7 @@ private newtype GvnBase = * expression with this `GVN` and using its `toString` and `getLocation` * methods. */ -class GVN extends GvnBase { +deprecated class GVN extends GvnBase { GVN() { this instanceof GvnBase } /** Gets an expression that has this GVN. */ @@ -503,7 +507,7 @@ private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceE /** Gets the global value number of expression `e`. */ cached -GVN globalValueNumber(Expr e) { +deprecated GVN globalValueNumber(Expr e) { exists(int val, Type t | mk_IntConst(val, t, e) and result = GVN_IntConst(val, t) diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql index c8bf3842773..b0ce7fcce6d 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql @@ -15,6 +15,7 @@ import cpp +pragma[nomagic] predicate beforeArrayAccess(Variable v, ArrayExpr access, Expr before) { exists(LogicalAndExpr andexpr | access.getArrayOffset() = v.getAnAccess() and @@ -23,6 +24,7 @@ predicate beforeArrayAccess(Variable v, ArrayExpr access, Expr before) { ) } +pragma[nomagic] predicate afterArrayAccess(Variable v, ArrayExpr access, Expr after) { exists(LogicalAndExpr andexpr | access.getArrayOffset() = v.getAnAccess() and diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index f32f416b540..5cfd60bc84c 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.6 + +No user-facing changes. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +No user-facing changes. + ## 0.4.3 ### Minor Analysis Improvements diff --git a/cpp/ql/src/Critical/MissingCheckScanf.ql b/cpp/ql/src/Critical/MissingCheckScanf.ql index cdb48099818..29f1c2b07ad 100644 --- a/cpp/ql/src/Critical/MissingCheckScanf.ql +++ b/cpp/ql/src/Critical/MissingCheckScanf.ql @@ -115,7 +115,8 @@ BasicBlock blockGuardedBy(int value, string op, ScanfFunctionCall call) { from ScanfOutput output, ScanfFunctionCall call, Access access where output.getCall() = call and - output.hasGuardedAccess(access, false) + output.hasGuardedAccess(access, false) and + not exists(DeallocationExpr dealloc | dealloc.getFreedExpr() = access) select access, "This variable is read, but may not have been written. " + "It should be guarded by a check that the $@ returns at least " + diff --git a/cpp/ql/src/JPL_C/LOC-4/Rule 23/MismatchedIfdefs.ql b/cpp/ql/src/JPL_C/LOC-4/Rule 23/MismatchedIfdefs.ql index e9c619167de..1e5fed2bfb7 100644 --- a/cpp/ql/src/JPL_C/LOC-4/Rule 23/MismatchedIfdefs.ql +++ b/cpp/ql/src/JPL_C/LOC-4/Rule 23/MismatchedIfdefs.ql @@ -66,9 +66,7 @@ class ElseDirective extends Directive { override predicate mismatched() { depth() < 1 } } -class EndifDirective extends Directive { - EndifDirective() { this instanceof PreprocessorEndif } - +class EndifDirective extends Directive instanceof PreprocessorEndif { override int depthChange() { result = -1 } override predicate mismatched() { depth() < 0 } diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index 26c8ae4c258..af4bd8c61a3 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -26,11 +26,11 @@ predicate intentionallyReturnsStackPointer(Function f) { class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" } - override predicate isSource(DataFlow::Node source) { + override predicate isSource(Instruction source) { // Holds if `source` is a node that represents the use of a stack variable exists(VariableAddressInstruction var, Function func | - var = source.asInstruction() and - func = var.getEnclosingFunction() and + var = source and + func = source.getEnclosingFunction() and var.getAstVariable() instanceof StackVariable and // Pointer-to-member types aren't properly handled in the dbscheme. not var.getResultType() instanceof PointerToMemberType and @@ -40,7 +40,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { ) } - override predicate isSink(DataFlow::Node sink) { + override predicate isSink(Operand sink) { // Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in // a `ReturnValueInstruction`. // We use the `StoreInstruction` instead of the instruction that defines the @@ -48,7 +48,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { exists(StoreInstruction store | store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof IRReturnVariable and - sink.asOperand() = store.getSourceValueOperand() + sink = store.getSourceValueOperand() ) } @@ -77,10 +77,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { * } * ``` */ - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node2.asInstruction().(FieldAddressInstruction).getObjectAddressOperand() = node1.asOperand() + override predicate isAdditionalFlowStep(Operand node1, Instruction node2) { + node2.(FieldAddressInstruction).getObjectAddressOperand() = node1 or - node2.asInstruction().(PointerOffsetInstruction).getLeftOperand() = node1.asOperand() + node2.(PointerOffsetInstruction).getLeftOperand() = node1 } } @@ -89,6 +89,6 @@ from ReturnStackAllocatedMemoryConfig conf where conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and - source.getNode().asInstruction() = var -select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(), - var.getAst().toString() + source.getInstruction() = var +select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.", + var.getAst(), var.getAst().toString() diff --git a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql index db1816f7a72..bb62cfc1755 100644 --- a/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql +++ b/cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql @@ -22,37 +22,40 @@ import PathGraph class UnsafeUseOfThisConfig extends MustFlowConfiguration { UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" } - override predicate isSource(DataFlow::Node source) { isSource(source, _, _) } + override predicate isSource(Instruction source) { isSource(source, _, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(Operand sink) { isSink(sink, _) } } -/** Holds if `instr` is a `this` pointer used by the call instruction `call`. */ -predicate isSink(DataFlow::Node sink, CallInstruction call) { +/** Holds if `sink` is a `this` pointer used by the call instruction `call`. */ +predicate isSink(Operand sink, CallInstruction call) { exists(PureVirtualFunction func | call.getStaticCallTarget() = func and - call.getThisArgument() = sink.asInstruction() and + call.getThisArgumentOperand() = sink and // Weed out implicit calls to destructors of a base class not func instanceof Destructor ) } -/** Holds if `init` initializes the `this` pointer in class `c`. */ -predicate isSource(DataFlow::Node source, string msg, Class c) { - exists(InitializeParameterInstruction init | init = source.asInstruction() | - ( - exists(Constructor func | - not func instanceof CopyConstructor and - not func instanceof MoveConstructor and - func = init.getEnclosingFunction() and - msg = "construction" - ) - or - init.getEnclosingFunction() instanceof Destructor and msg = "destruction" - ) and - init.getIRVariable() instanceof IRThisVariable and - init.getEnclosingFunction().getDeclaringType() = c - ) +/** + * Holds if `source` initializes the `this` pointer in class `c`. + * + * The string `msg` describes whether the enclosing function is a + * constructor or destructor. + */ +predicate isSource(InitializeParameterInstruction source, string msg, Class c) { + ( + exists(Constructor func | + not func instanceof CopyConstructor and + not func instanceof MoveConstructor and + func = source.getEnclosingFunction() and + msg = "construction" + ) + or + source.getEnclosingFunction() instanceof Destructor and msg = "destruction" + ) and + source.getIRVariable() instanceof IRThisVariable and + source.getEnclosingFunction().getDeclaringType() = c } /** @@ -68,8 +71,8 @@ predicate flows( ) { exists(UnsafeUseOfThisConfig conf | conf.hasFlowPath(source, sink) and - isSource(source.getNode(), msg, sourceClass) and - isSink(sink.getNode(), call) + isSource(source.getInstruction(), msg, sourceClass) and + isSink(sink.getInstruction().getAUse(), call) ) } diff --git a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql index 47ed2b704d5..4dacffb6a55 100644 --- a/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql +++ b/cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql @@ -12,8 +12,8 @@ */ /* - * Note: this query is not assigned a precision yet because we don't want it on - * LGTM until its performance is well understood. + * Note: this query is not assigned a precision yet because we don't want it + * to be included in query suites until its performance is well understood. */ import cpp diff --git a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll index 352cf86ddd5..967a9987a4f 100644 --- a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll +++ b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.qll @@ -52,7 +52,7 @@ class Library extends LibraryT { // The versions reported for C/C++ dependencies are just the versions that // happen to be installed on the system where the build takes place. // Reporting those versions is likely to cause misunderstandings, both for - // people reading them and for the vulnerability checker of lgtm. + // people reading them and for vulnerability checkers. result = "unknown" } diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 928c9942177..f000e25df52 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -16,9 +16,10 @@ import cpp import semmle.code.cpp.security.FunctionWithWrappers -import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking -import TaintedWithPath +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.ir.IR +import semmle.code.cpp.ir.dataflow.TaintTracking +import DataFlow::PathGraph /** * A function for opening a file. @@ -46,19 +47,71 @@ class FileFunction extends FunctionWithWrappers { override predicate interestingArg(int arg) { arg = 0 } } -class TaintedPathConfiguration extends TaintTrackingConfiguration { - override predicate isSink(Element tainted) { - exists(FileFunction fileFunction | fileFunction.outermostWrapperFunctionCall(tainted, _)) +Expr asSinkExpr(DataFlow::Node node) { + result = + node.asOperand() + .(SideEffectOperand) + .getUse() + .(ReadSideEffectInstruction) + .getArgumentDef() + .getUnconvertedResultExpression() +} + +/** + * Holds for a variable that has any kind of upper-bound check anywhere in the program. + * This is biased towards being inclusive and being a coarse overapproximation because + * there are a lot of valid ways of doing an upper bounds checks if we don't consider + * where it occurs, for example: + * ```cpp + * if (x < 10) { sink(x); } + * + * if (10 > y) { sink(y); } + * + * if (z > 10) { z = 10; } + * sink(z); + * ``` + */ +predicate hasUpperBoundsCheck(Variable var) { + exists(RelationalOperation oper, VariableAccess access | + oper.getAnOperand() = access and + access.getTarget() = var and + // Comparing to 0 is not an upper bound check + not oper.getAnOperand().getValue() = "0" + ) +} + +class TaintedPathConfiguration extends TaintTracking::Configuration { + TaintedPathConfiguration() { this = "TaintedPathConfiguration" } + + override predicate isSource(DataFlow::Node node) { node instanceof FlowSource } + + override predicate isSink(DataFlow::Node node) { + exists(FileFunction fileFunction | + fileFunction.outermostWrapperFunctionCall(asSinkExpr(node), _) + ) + } + + override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) } + + override predicate isSanitizer(DataFlow::Node node) { + node.asExpr().(Call).getTarget().getUnspecifiedType() instanceof ArithmeticType + or + exists(LoadInstruction load, Variable checkedVar | + load = node.asInstruction() and + checkedVar = load.getSourceAddress().(VariableAddressInstruction).getAstVariable() and + hasUpperBoundsCheck(checkedVar) + ) } } from - FileFunction fileFunction, Expr taintedArg, Expr taintSource, PathNode sourceNode, - PathNode sinkNode, string taintCause, string callChain + FileFunction fileFunction, Expr taintedArg, FlowSource taintSource, TaintedPathConfiguration cfg, + DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string callChain where + taintedArg = asSinkExpr(sinkNode.getNode()) and fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and - taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and - isUserInput(taintSource, taintCause) + cfg.hasFlowPath(sourceNode, sinkNode) and + taintSource = sourceNode.getNode() select taintedArg, sourceNode, sinkNode, "This argument to a file access function is derived from $@ and then passed to " + callChain + ".", - taintSource, "user input (" + taintCause + ")" + taintSource, "user input (" + taintSource.getSourceType() + ")" diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql index bb38609927e..ffadb381a76 100644 --- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql +++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql @@ -13,7 +13,7 @@ import cpp import semmle.code.cpp.commons.Environment -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath /** A call that prints its arguments to `stdout`. */ diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index b46314d8454..f3ff16e8f7b 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -15,7 +15,7 @@ import cpp import semmle.code.cpp.security.Security import semmle.code.cpp.security.FunctionWithWrappers -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath class SqlLikeFunction extends FunctionWithWrappers { diff --git a/cpp/ql/src/Security/CWE/CWE-114/UncontrolledProcessOperation.ql b/cpp/ql/src/Security/CWE/CWE-114/UncontrolledProcessOperation.ql index 7cbb0d81d49..883a6b07423 100644 --- a/cpp/ql/src/Security/CWE/CWE-114/UncontrolledProcessOperation.ql +++ b/cpp/ql/src/Security/CWE/CWE-114/UncontrolledProcessOperation.ql @@ -14,7 +14,7 @@ import cpp import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath predicate isProcessOperationExplanation(Expr arg, string processOperation) { diff --git a/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql b/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql index a2d74e7557a..8f8d98900f2 100644 --- a/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql @@ -16,7 +16,7 @@ import semmle.code.cpp.security.BufferWrite import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath /* diff --git a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql index 33a6ee1d5f5..2001b1a308c 100644 --- a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql +++ b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql @@ -116,10 +116,6 @@ class ImproperArrayIndexValidationConfig extends TaintTracking::Configuration { } } -/** Gets `str` where the first letter has been lowercased. */ -bindingset[str] -string lowerFirst(string str) { result = str.prefix(1).toLowerCase() + str.suffix(1) } - from ImproperArrayIndexValidationConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink, string sourceType @@ -128,4 +124,4 @@ where isFlowSource(source.getNode(), sourceType) select sink.getNode(), source, sink, "An array indexing expression depends on $@ that might be outside the bounds of the array.", - source.getNode(), lowerFirst(sourceType) + source.getNode(), sourceType diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql index 11cbfe16a0d..3a5cb7931b2 100644 --- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql +++ b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql @@ -16,7 +16,7 @@ import cpp import semmle.code.cpp.security.Security import semmle.code.cpp.security.FunctionWithWrappers -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath class Configuration extends TaintTrackingConfiguration { diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql index a4fd672f518..b37e34c296c 100644 --- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql +++ b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql @@ -16,7 +16,7 @@ import cpp import semmle.code.cpp.security.FunctionWithWrappers import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath class Configuration extends TaintTrackingConfiguration { diff --git a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql index 762fcf573d1..ff2e7e924df 100644 --- a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql @@ -12,7 +12,7 @@ import cpp import semmle.code.cpp.commons.NullTermination -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl /** A user-controlled expression that may not be null terminated. */ class TaintSource extends VariableAccess { diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index 350005194ac..07fbdc1ff44 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -15,7 +15,7 @@ import cpp import semmle.code.cpp.security.Overflow import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath import Bounded diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql index e54951b33e7..6034b4f5ffd 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql @@ -17,7 +17,7 @@ import cpp import semmle.code.cpp.security.Overflow import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl predicate isMaxValue(Expr mie) { exists(MacroInvocation mi | diff --git a/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql b/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql index 7cbd53ebf8a..19fe7df4c44 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql @@ -15,7 +15,7 @@ import cpp import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl /** Holds if `expr` might overflow. */ predicate outOfBoundsExpr(Expr expr, string kind) { diff --git a/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql b/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql index 814c6aff21b..06c4ee5efe5 100644 --- a/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql +++ b/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql @@ -12,7 +12,7 @@ * external/cwe/cwe-290 */ -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath predicate hardCodedAddressOrIP(StringLiteral txt) { diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql index ec78e6b63fb..6858dffbfa8 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql @@ -19,7 +19,25 @@ import semmle.code.cpp.ir.dataflow.TaintTracking import DataFlow::PathGraph /** - * A taint flow configuration for flow from user input to a buffer write. + * A buffer write into a sensitive expression. + */ +class SensitiveBufferWrite extends Expr instanceof BufferWrite::BufferWrite { + SensitiveBufferWrite() { super.getDest() instanceof SensitiveExpr } + + /** + * Gets a data source of this operation. + */ + Expr getASource() { result = super.getASource() } + + /** + * Gets the destination buffer of this operation. + */ + Expr getDest() { result = super.getDest() } +} + +/** + * A taint flow configuration for flow from user input to a buffer write + * into a sensitive expression. */ class ToBufferConfiguration extends TaintTracking::Configuration { ToBufferConfiguration() { this = "ToBufferConfiguration" } @@ -31,18 +49,17 @@ class ToBufferConfiguration extends TaintTracking::Configuration { } override predicate isSink(DataFlow::Node sink) { - exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr()) + exists(SensitiveBufferWrite w | w.getASource() = sink.asExpr()) } } from - ToBufferConfiguration config, BufferWrite::BufferWrite w, DataFlow::PathNode sourceNode, - DataFlow::PathNode sinkNode, FlowSource source, SensitiveExpr dest + ToBufferConfiguration config, SensitiveBufferWrite w, DataFlow::PathNode sourceNode, + DataFlow::PathNode sinkNode, FlowSource source where config.hasFlowPath(sourceNode, sinkNode) and sourceNode.getNode() = source and - w.getASource() = sinkNode.getNode().asExpr() and - dest = w.getDest() + w.getASource() = sinkNode.getNode().asExpr() select w, sourceNode, sinkNode, - "This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@.", source, - "user input (" + source.getSourceType() + ")" + "This write into buffer '" + w.getDest().toString() + "' may contain unencrypted data from $@.", + source, "user input (" + source.getSourceType() + ")" diff --git a/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql b/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql index 14cd2a2188a..c5d7f2cbb61 100644 --- a/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql +++ b/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql @@ -12,7 +12,7 @@ * external/cwe/cwe-807 */ -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl import TaintedWithPath predicate sensitiveCondition(Expr condition, Expr raise) { diff --git a/cpp/ql/src/change-notes/2022-12-15-no-scanf-buffer-allocation-warnings.md b/cpp/ql/src/change-notes/2022-12-15-no-scanf-buffer-allocation-warnings.md new file mode 100644 index 00000000000..fc02f7cbf3a --- /dev/null +++ b/cpp/ql/src/change-notes/2022-12-15-no-scanf-buffer-allocation-warnings.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `cpp/missing-check-scanf` query no longer reports the free'ing of `scanf` output variables as potential reads. \ No newline at end of file diff --git a/cpp/ql/src/change-notes/released/0.4.4.md b/cpp/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/cpp/ql/src/change-notes/released/0.4.5.md b/cpp/ql/src/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/cpp/ql/src/change-notes/released/0.4.6.md b/cpp/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/cpp/ql/src/jsf/4.09 Style/Naming.qll b/cpp/ql/src/jsf/4.09 Style/Naming.qll index 264a6bac219..5df3724a067 100644 --- a/cpp/ql/src/jsf/4.09 Style/Naming.qll +++ b/cpp/ql/src/jsf/4.09 Style/Naming.qll @@ -1,4 +1,4 @@ -/* +/** * Common functions for implementing naming conventions * * Naming rules are the following: diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 3a44ef8b743..b8b2f8a31ca 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.4-dev +version: 0.5.0-dev groups: - cpp - queries diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected index e69de29bb2d..6f00f28e455 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected @@ -0,0 +1,2 @@ +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:9,8-47) +WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:20,49-74) diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp index ce758af691b..e80991d4fb3 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp @@ -1,18 +1,6 @@ #include "../shared.h" - - - - - - - - - int main() { - - - sink(_strdup(getenv("VAR"))); // $ ir MISSING: ast sink(strdup(getenv("VAR"))); // $ ast,ir sink(unmodeled_function(getenv("VAR"))); // clean by assumption @@ -59,9 +47,6 @@ void test_outparams() { sink(p2); // $ ir MISSING: ast } - - - struct XY { int x; int y; @@ -230,24 +215,17 @@ void test_recv() { // --- send and related functions --- -int send(int, const void*, int, int); - -void test_send(char* buffer, int length) { - send(0, buffer, length, 0); // $ remote -} - struct iovec { void *iov_base; unsigned iov_len; }; int readv(int, const struct iovec*, int); -int writev(int, const struct iovec*, int); void sink(const iovec* iovs); void sink(iovec); -int test_readv_and_writev(iovec* iovs) { +void test_readv_and_writev(iovec* iovs) { readv(0, iovs, 16); sink(iovs); // $ast,ir sink(iovs[0]); // $ast,ir @@ -256,6 +234,4 @@ int test_readv_and_writev(iovec* iovs) { char* p = (char*)iovs[1].iov_base; sink(p); // $ MISSING: ast,ir sink(*p); // $ MISSING: ast,ir - - writev(0, iovs, 16); // $ remote } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql deleted file mode 100644 index 4fbbe8fa3bf..00000000000 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql +++ /dev/null @@ -1,20 +0,0 @@ -/** This tests that we are able to detect remote flow sinks. */ - -import cpp -import TestUtilities.InlineExpectationsTest -import semmle.code.cpp.security.FlowSources - -class RemoteFlowSinkTest extends InlineExpectationsTest { - RemoteFlowSinkTest() { this = "RemoteFlowSinkTest" } - - override string getARelevantTag() { result = "remote" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "remote" and - value = "" and - exists(RemoteFlowSink node | - location = node.getLocation() and - element = node.toString() - ) - } -} diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected index e69de29bb2d..5c235d0802d 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected @@ -0,0 +1,2 @@ +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:10,8-47) +WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:21,3-28) diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected index e69de29bb2d..b1d79c1079e 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected @@ -0,0 +1,2 @@ +WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (global.ql:8,3-47) +WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (global.ql:12,3-53) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 11bb0c21789..8f7078984cb 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -6,6 +6,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -91,3 +93,6 @@ postWithInFlow | test.cpp:499:4:499:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:505:35:505:35 | x [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index cb3f20d9e53..6a26a6f13ae 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -21,6 +21,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -635,3 +637,6 @@ postWithInFlow | true_upon_entry.cpp:101:18:101:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. | | true_upon_entry.cpp:102:5:102:5 | x [post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp index 131f0f5d05d..f9df8c9497c 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp @@ -87,7 +87,7 @@ Top *identity(Top *top) { void callIdentityFunctions(Top *top, Bottom *bottom) { identity(bottom)->isSink(source()); // $ MISSING: ast,ir - identity(top)->isSink(source()); // now flow + identity(top)->isSink(source()); // no flow } using SinkFunctionType = void (*)(int); diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected index f66ef23ba74..e0470aac85d 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected @@ -12,6 +12,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -156,3 +158,6 @@ postWithInFlow | struct_init.c:24:11:24:12 | ab [inner post update] | PostUpdateNode should not be the target of local flow. | | struct_init.c:36:17:36:24 | nestedAB [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index 4dee8fb627f..dd2d9f54f35 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -15,6 +15,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -1324,3 +1326,6 @@ postWithInFlow | struct_init.c:46:16:46:24 | pointerAB [post update] | PostUpdateNode should not be the target of local flow. | | struct_init.c:46:16:46:24 | pointerAB [post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected index cdea135e301..b1e0d3635a3 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected @@ -1,3 +1,4 @@ +WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (tainted.ql:5,3-29) | test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | | | test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | | | test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv | | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected index ac95d5659a3..5d732c45866 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected @@ -1,3 +1,8 @@ +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted_diff.ql:5,35-54) +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted_diff.ql:12,7-26) +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted_diff.ql:16,3-22) +WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (tainted_diff.ql:11,3-34) +WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (tainted_diff.ql:17,7-38) | test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | | test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | AST only | | test.cpp:38:23:38:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected index 01d8f5092ed..4b439122fa3 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected @@ -1,3 +1,5 @@ +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted_ir.ql:3,35-50) +WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted_ir.ql:9,3-18) | test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv | | test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:40 | (const char *)... | | test.cpp:23:23:23:28 | call to getenv | test.cpp:25:6:25:29 | ! ... | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected similarity index 100% rename from cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.expected rename to cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql new file mode 100644 index 00000000000..cb687f1d3bf --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql @@ -0,0 +1,32 @@ +/** This tests that we are able to detect local flow sources. */ + +import cpp +import TestUtilities.InlineExpectationsTest +import semmle.code.cpp.security.FlowSources + +class LocalFlowSourceTest extends InlineExpectationsTest { + LocalFlowSourceTest() { this = "LocalFlowSourceTest" } + + override string getARelevantTag() { result = "local_source" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "local_source" and + exists(LocalFlowSource node, int n | + n = + strictcount(LocalFlowSource otherNode | + node.getLocation().getStartLine() = otherNode.getLocation().getStartLine() + ) and + ( + n = 1 and value = "" + or + // If there is more than one node on this line + // we specify the location explicitly. + n > 1 and + value = + node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn() + ) and + location = node.getLocation() and + element = node.toString() + ) + } +} diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected similarity index 100% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.expected rename to cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql new file mode 100644 index 00000000000..703b62b9ffc --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql @@ -0,0 +1,59 @@ +/** This tests that we are able to detect remote flow sources and sinks. */ + +import cpp +import TestUtilities.InlineExpectationsTest +import semmle.code.cpp.security.FlowSources + +class RemoteFlowSourceTest extends InlineExpectationsTest { + RemoteFlowSourceTest() { this = "RemoteFlowSourceTest" } + + override string getARelevantTag() { result = "remote_source" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "remote_source" and + exists(RemoteFlowSource node, int n | + n = + strictcount(RemoteFlowSource otherNode | + node.getLocation().getStartLine() = otherNode.getLocation().getStartLine() + ) and + ( + n = 1 and value = "" + or + // If there is more than one node on this line + // we specify the location explicitly. + n > 1 and + value = + node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn() + ) and + location = node.getLocation() and + element = node.toString() + ) + } +} + +class RemoteFlowSinkTest extends InlineExpectationsTest { + RemoteFlowSinkTest() { this = "RemoteFlowSinkTest" } + + override string getARelevantTag() { result = "remote_sink" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "remote_sink" and + exists(RemoteFlowSink node, int n | + n = + strictcount(RemoteFlowSink otherNode | + node.getLocation().getStartLine() = otherNode.getLocation().getStartLine() + ) and + ( + n = 1 and value = "" + or + // If there is more than one node on this line + // we specify the location explicitly. + n > 1 and + value = + node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn() + ) and + location = node.getLocation() and + element = node.toString() + ) + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp new file mode 100644 index 00000000000..fcc4ee0a315 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp @@ -0,0 +1,52 @@ +char *getenv(const char *name); +char *secure_getenv(const char *name); +wchar_t *_wgetenv(const wchar_t *name); + +void test_getenv() { + void *var1 = getenv("VAR"); // $ local_source + void *var2 = secure_getenv("VAR"); // $ local_source + void *var3 = _wgetenv(L"VAR"); // $ local_source +} + +int send(int, const void*, int, int); + +void test_send(char* buffer, int length) { + send(0, buffer, length, 0); // $ remote_sink +} + +struct iovec { + void *iov_base; + unsigned iov_len; +}; + +int readv(int, const struct iovec*, int); +int writev(int, const struct iovec*, int); + +void test_readv_and_writev(iovec* iovs) { + readv(0, iovs, 16); // $ remote_source + writev(0, iovs, 16); // $ remote_sink +} + +struct FILE; + +int fscanf(FILE *stream, const char *format, ...); +int scanf(const char *format, ...); + +void test_scanf(FILE *stream, int *d, char *buf) { + scanf(""); // Not a local source, as there are no output arguments + fscanf(stream, ""); // Not a remote source, as there are no output arguments + scanf("%d", d); // $ local_source + fscanf(stream, "%d", d); // $ remote_source + scanf("%d %s", d, buf); // $ local_source=40:18 local_source=40:21 + fscanf(stream, "%d %s", d, buf); // $ remote_source=41:27 remote_source=41:30 +} + +struct addrinfo; + +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); + +void test_inet(char *hostname, char *servname, struct addrinfo *hints) { + addrinfo *res; + int ret = getaddrinfo(hostname, servname, hints, &res); // $ remote_source +} diff --git a/cpp/ql/test/library-tests/floats/float128/errors.expected b/cpp/ql/test/library-tests/floats/float128/errors.expected index d7891f3e9b6..2f163e66cb0 100644 --- a/cpp/ql/test/library-tests/floats/float128/errors.expected +++ b/cpp/ql/test/library-tests/floats/float128/errors.expected @@ -1,4 +1,3 @@ | file://:0:0:0:0 | There was an error during this compilation | | float128.cpp:1:39:1:39 | 128-bit floating-point types are not supported in this configuration | -| float128.cpp:2:30:2:30 | an attribute specifies a mode incompatible with '' | -| float128.cpp:2:41:2:41 | invalid combination of type specifiers | +| float128.cpp:2:30:2:30 | 128-bit floating-point types are not supported in this configuration | diff --git a/cpp/ql/test/library-tests/floats/float128/usertypes.expected b/cpp/ql/test/library-tests/floats/float128/usertypes.expected index 84a38d93967..42b6612aff9 100644 --- a/cpp/ql/test/library-tests/floats/float128/usertypes.expected +++ b/cpp/ql/test/library-tests/floats/float128/usertypes.expected @@ -1,4 +1,5 @@ | float128.cpp:1:50:1:60 | _Complex128 | file://:0:0:0:0 | | +| float128.cpp:2:41:2:49 | _Float128 | file://:0:0:0:0 | | | float128.cpp:13:29:13:54 | __is_floating_point_helper | float128.cpp:10:8:10:17 | false_type | | float128.cpp:14:19:14:51 | __is_floating_point_helper | float128.cpp:11:8:11:16 | true_type | | float128.cpp:15:19:15:52 | __is_floating_point_helper | float128.cpp:11:8:11:16 | true_type | diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected index 086fa0415b7..5e44737a253 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected @@ -52,6 +52,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -125,3 +127,6 @@ postWithInFlow | static_init_templates.cpp:21:2:21:4 | val [post update] | PostUpdateNode should not be the target of local flow. | | try_catch.cpp:7:8:7:8 | call to exception | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected index 70f8446ec5a..8b1094228a9 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected @@ -1463,6 +1463,8 @@ uniqueNodeToString missingToString parameterCallable localFlowIsLocal +readStepIsLocal +storeStepIsLocal compatibleTypesReflexive unreachableNodeCCtx localCallNodes @@ -2711,3 +2713,8 @@ postWithInFlow | whilestmt.c:40:7:40:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. | | whilestmt.c:42:7:42:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge +uniqueParameterNodeAtPosition +| ir.cpp:724:6:724:13 | TryCatch | 0 | ir.cpp:735:22:735:22 | *s | Parameters with overlapping positions. | +| ir.cpp:724:6:724:13 | TryCatch | 0 | ir.cpp:738:24:738:24 | *e | Parameters with overlapping positions. | +uniqueParameterNodePosition +uniqueContentApprox diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected index d5d46ee0b72..69c21b5e0b1 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_gvn.expected @@ -1,3 +1,4 @@ +WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9) | test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 | | test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 | | test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected index e69de29bb2d..d94d58ad5ea 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_uniqueness.expected @@ -0,0 +1,3 @@ +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30) +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47) +WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21) diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected index b838a13d5af..810c83f197f 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/diff_ir_expr.expected @@ -1,3 +1,4 @@ +WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51) | test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only | | test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only | | test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected index ce11cb53c58..bbedf4ecc3f 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected @@ -1,19 +1,21 @@ -| test.cpp:30:7:30:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:29:3:29:7 | call to scanf | call to scanf | -| test.cpp:46:7:46:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:45:3:45:7 | call to scanf | call to scanf | -| test.cpp:63:7:63:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:62:3:62:7 | call to scanf | call to scanf | -| test.cpp:75:7:75:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:74:3:74:7 | call to scanf | call to scanf | -| test.cpp:87:7:87:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:86:3:86:8 | call to fscanf | call to fscanf | -| test.cpp:94:7:94:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:93:3:93:8 | call to sscanf | call to sscanf | -| test.cpp:143:8:143:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:141:7:141:11 | call to scanf | call to scanf | -| test.cpp:152:8:152:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:150:7:150:11 | call to scanf | call to scanf | -| test.cpp:184:8:184:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:183:7:183:11 | call to scanf | call to scanf | -| test.cpp:203:8:203:8 | j | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:200:7:200:11 | call to scanf | call to scanf | -| test.cpp:227:9:227:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:225:25:225:29 | call to scanf | call to scanf | -| test.cpp:231:9:231:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:229:14:229:18 | call to scanf | call to scanf | -| test.cpp:243:7:243:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:242:3:242:7 | call to scanf | call to scanf | -| test.cpp:251:7:251:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:250:3:250:7 | call to scanf | call to scanf | -| test.cpp:259:7:259:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:258:3:258:7 | call to scanf | call to scanf | -| test.cpp:271:7:271:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:270:3:270:7 | call to scanf | call to scanf | -| test.cpp:281:8:281:12 | ptr_i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:280:3:280:7 | call to scanf | call to scanf | -| test.cpp:289:7:289:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:288:3:288:7 | call to scanf | call to scanf | -| test.cpp:383:25:383:25 | u | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:382:6:382:11 | call to sscanf | call to sscanf | +| test.cpp:35:7:35:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:34:3:34:7 | call to scanf | call to scanf | +| test.cpp:51:7:51:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:50:3:50:7 | call to scanf | call to scanf | +| test.cpp:68:7:68:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:67:3:67:7 | call to scanf | call to scanf | +| test.cpp:80:7:80:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:79:3:79:7 | call to scanf | call to scanf | +| test.cpp:90:8:90:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:89:3:89:7 | call to scanf | call to scanf | +| test.cpp:98:8:98:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:97:3:97:7 | call to scanf | call to scanf | +| test.cpp:108:7:108:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:107:3:107:8 | call to fscanf | call to fscanf | +| test.cpp:115:7:115:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:114:3:114:8 | call to sscanf | call to sscanf | +| test.cpp:164:8:164:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:162:7:162:11 | call to scanf | call to scanf | +| test.cpp:173:8:173:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:171:7:171:11 | call to scanf | call to scanf | +| test.cpp:205:8:205:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:204:7:204:11 | call to scanf | call to scanf | +| test.cpp:224:8:224:8 | j | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:221:7:221:11 | call to scanf | call to scanf | +| test.cpp:248:9:248:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:246:25:246:29 | call to scanf | call to scanf | +| test.cpp:252:9:252:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:250:14:250:18 | call to scanf | call to scanf | +| test.cpp:264:7:264:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:263:3:263:7 | call to scanf | call to scanf | +| test.cpp:272:7:272:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:271:3:271:7 | call to scanf | call to scanf | +| test.cpp:280:7:280:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:279:3:279:7 | call to scanf | call to scanf | +| test.cpp:292:7:292:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:291:3:291:7 | call to scanf | call to scanf | +| test.cpp:302:8:302:12 | ptr_i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:301:3:301:7 | call to scanf | call to scanf | +| test.cpp:310:7:310:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:309:3:309:7 | call to scanf | call to scanf | +| test.cpp:404:25:404:25 | u | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:403:6:403:11 | call to sscanf | call to sscanf | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp index e621936dc33..38af4d7efcd 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp @@ -19,6 +19,11 @@ FILE *get_a_stream(); const char *get_a_string(); extern locale_t get_a_locale(); +typedef long size_t; + +void *malloc(size_t size); +void free(void *ptr); + int main() { // --- simple cases --- @@ -78,6 +83,22 @@ int main() use(i); // GOOD } + { + int *i = (int*)malloc(sizeof(int)); // Allocated variable + + scanf("%d", i); + use(*i); // BAD + free(i); // GOOD + } + + { + int *i = new int; // Allocated variable + + scanf("%d", i); + use(*i); // BAD + delete i; // GOOD + } + // --- different scanf functions --- { diff --git a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected index 067ba7ab4fc..7f1ee1356ab 100644 --- a/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected +++ b/cpp/ql/test/query-tests/Critical/UnsafeUseOfThis/UnsafeUseOfThis.expected @@ -1,103 +1,61 @@ edges -| test.cpp:7:3:7:3 | this | test.cpp:8:12:8:15 | Load | -| test.cpp:8:12:8:15 | Load | test.cpp:8:12:8:15 | this | +| test.cpp:7:3:7:3 | B | test.cpp:8:12:8:15 | this | | test.cpp:8:12:8:15 | this | test.cpp:34:16:34:16 | x | -| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | Load | -| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | Unary | -| test.cpp:12:5:12:5 | Load | test.cpp:12:5:12:5 | b | -| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (A)... | -| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (reference dereference) | -| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | Unary | -| test.cpp:15:3:15:4 | this | test.cpp:16:5:16:5 | Load | -| test.cpp:16:5:16:5 | Load | test.cpp:16:5:16:5 | this | -| test.cpp:16:5:16:5 | Unary | file://:0:0:0:0 | (A *)... | -| test.cpp:16:5:16:5 | this | test.cpp:16:5:16:5 | Unary | -| test.cpp:21:3:21:3 | Unary | test.cpp:21:13:21:13 | ConvertToNonVirtualBase | -| test.cpp:21:3:21:3 | this | test.cpp:21:3:21:3 | Unary | -| test.cpp:21:3:21:3 | this | test.cpp:22:12:22:15 | Load | -| test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | Load | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | test.cpp:7:3:7:3 | this | +| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | b | +| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | (A)... | +| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | (reference dereference) | +| test.cpp:15:3:15:4 | ~B | test.cpp:16:5:16:5 | this | +| test.cpp:16:5:16:5 | this | file://:0:0:0:0 | (A *)... | +| test.cpp:21:3:21:3 | C | test.cpp:21:13:21:13 | call to B | +| test.cpp:21:3:21:3 | C | test.cpp:22:12:22:15 | this | +| test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | this | +| test.cpp:21:13:21:13 | call to B | test.cpp:7:3:7:3 | B | | test.cpp:22:12:22:15 | (B *)... | test.cpp:34:16:34:16 | x | -| test.cpp:22:12:22:15 | Load | test.cpp:22:12:22:15 | this | -| test.cpp:22:12:22:15 | Unary | test.cpp:22:12:22:15 | (B *)... | -| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | Unary | -| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | Unary | -| test.cpp:25:7:25:10 | Load | test.cpp:25:7:25:10 | this | -| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (A *)... | -| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (B *)... | -| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | Unary | -| test.cpp:31:3:31:3 | this | test.cpp:31:12:31:15 | Load | -| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | Unary | +| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | (B *)... | +| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | (A *)... | +| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | (B *)... | +| test.cpp:31:3:31:3 | D | test.cpp:31:12:31:15 | this | +| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | (reference to) | | test.cpp:31:11:31:15 | (reference to) | test.cpp:11:8:11:8 | b | -| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | Unary | -| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (B)... | -| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (reference to) | -| test.cpp:31:12:31:15 | Load | test.cpp:31:12:31:15 | this | -| test.cpp:31:12:31:15 | Unary | test.cpp:31:11:31:15 | * ... | -| test.cpp:31:12:31:15 | this | test.cpp:31:12:31:15 | Unary | -| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | Load | -| test.cpp:35:3:35:3 | Load | test.cpp:35:3:35:3 | x | -| test.cpp:35:3:35:3 | Unary | test.cpp:35:3:35:3 | (A *)... | -| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | Unary | -| test.cpp:47:3:47:3 | this | test.cpp:48:10:48:13 | Load | -| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:10:48:13 | Unary | -| test.cpp:48:10:48:13 | Load | test.cpp:48:10:48:13 | this | -| test.cpp:48:10:48:13 | Unary | test.cpp:48:6:48:13 | (A *)... | -| test.cpp:48:10:48:13 | Unary | test.cpp:48:10:48:13 | (E *)... | -| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | Unary | +| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | (B)... | +| test.cpp:31:12:31:15 | this | test.cpp:31:11:31:15 | * ... | +| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | x | +| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | (A *)... | +| test.cpp:47:3:47:3 | F | test.cpp:48:10:48:13 | this | +| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:6:48:13 | (A *)... | +| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | (E *)... | nodes | file://:0:0:0:0 | (A *)... | semmle.label | (A *)... | -| test.cpp:7:3:7:3 | this | semmle.label | this | -| test.cpp:8:12:8:15 | Load | semmle.label | Load | +| test.cpp:7:3:7:3 | B | semmle.label | B | | test.cpp:8:12:8:15 | this | semmle.label | this | | test.cpp:11:8:11:8 | b | semmle.label | b | | test.cpp:12:5:12:5 | (A)... | semmle.label | (A)... | | test.cpp:12:5:12:5 | (reference dereference) | semmle.label | (reference dereference) | -| test.cpp:12:5:12:5 | Load | semmle.label | Load | -| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | -| test.cpp:12:5:12:5 | Unary | semmle.label | Unary | | test.cpp:12:5:12:5 | b | semmle.label | b | -| test.cpp:15:3:15:4 | this | semmle.label | this | -| test.cpp:16:5:16:5 | Load | semmle.label | Load | -| test.cpp:16:5:16:5 | Unary | semmle.label | Unary | +| test.cpp:15:3:15:4 | ~B | semmle.label | ~B | | test.cpp:16:5:16:5 | this | semmle.label | this | -| test.cpp:21:3:21:3 | Unary | semmle.label | Unary | -| test.cpp:21:3:21:3 | this | semmle.label | this | -| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | semmle.label | ConvertToNonVirtualBase | +| test.cpp:21:3:21:3 | C | semmle.label | C | +| test.cpp:21:13:21:13 | call to B | semmle.label | call to B | | test.cpp:22:12:22:15 | (B *)... | semmle.label | (B *)... | -| test.cpp:22:12:22:15 | Load | semmle.label | Load | -| test.cpp:22:12:22:15 | Unary | semmle.label | Unary | | test.cpp:22:12:22:15 | this | semmle.label | this | | test.cpp:25:7:25:10 | (A *)... | semmle.label | (A *)... | | test.cpp:25:7:25:10 | (B *)... | semmle.label | (B *)... | -| test.cpp:25:7:25:10 | Load | semmle.label | Load | -| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | -| test.cpp:25:7:25:10 | Unary | semmle.label | Unary | | test.cpp:25:7:25:10 | this | semmle.label | this | -| test.cpp:31:3:31:3 | this | semmle.label | this | +| test.cpp:31:3:31:3 | D | semmle.label | D | | test.cpp:31:11:31:15 | (B)... | semmle.label | (B)... | | test.cpp:31:11:31:15 | (reference to) | semmle.label | (reference to) | | test.cpp:31:11:31:15 | * ... | semmle.label | * ... | -| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | -| test.cpp:31:11:31:15 | Unary | semmle.label | Unary | -| test.cpp:31:12:31:15 | Load | semmle.label | Load | -| test.cpp:31:12:31:15 | Unary | semmle.label | Unary | | test.cpp:31:12:31:15 | this | semmle.label | this | | test.cpp:34:16:34:16 | x | semmle.label | x | | test.cpp:35:3:35:3 | (A *)... | semmle.label | (A *)... | -| test.cpp:35:3:35:3 | Load | semmle.label | Load | -| test.cpp:35:3:35:3 | Unary | semmle.label | Unary | | test.cpp:35:3:35:3 | x | semmle.label | x | -| test.cpp:47:3:47:3 | this | semmle.label | this | +| test.cpp:47:3:47:3 | F | semmle.label | F | | test.cpp:48:6:48:13 | (A *)... | semmle.label | (A *)... | | test.cpp:48:10:48:13 | (E *)... | semmle.label | (E *)... | -| test.cpp:48:10:48:13 | Load | semmle.label | Load | -| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | -| test.cpp:48:10:48:13 | Unary | semmle.label | Unary | | test.cpp:48:10:48:13 | this | semmle.label | this | #select -| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | this | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. | -| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | this | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. | -| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. | -| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | -| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | D | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. | +| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | ~B | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. | +| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | B | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | +| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | C | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected index 8f9d91fc1ad..b7b598a13c5 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected @@ -1,231 +1,117 @@ edges -| test.cpp:17:9:17:11 | & ... | test.cpp:17:9:17:11 | StoreValue | -| test.cpp:17:10:17:11 | Unary | test.cpp:17:9:17:11 | & ... | -| test.cpp:17:10:17:11 | mc | test.cpp:17:10:17:11 | Unary | -| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | StoreValue | -| test.cpp:23:17:23:19 | Store | test.cpp:25:9:25:11 | Load | -| test.cpp:23:17:23:19 | StoreValue | test.cpp:23:17:23:19 | Store | -| test.cpp:23:18:23:19 | Unary | test.cpp:23:17:23:19 | & ... | -| test.cpp:23:18:23:19 | mc | test.cpp:23:18:23:19 | Unary | -| test.cpp:25:9:25:11 | Load | test.cpp:25:9:25:11 | ptr | -| test.cpp:25:9:25:11 | ptr | test.cpp:25:9:25:11 | StoreValue | -| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | StoreValue | -| test.cpp:39:17:39:18 | Store | test.cpp:41:10:41:12 | Load | -| test.cpp:39:17:39:18 | StoreValue | test.cpp:39:17:39:18 | Store | -| test.cpp:39:17:39:18 | Unary | test.cpp:39:17:39:18 | (reference to) | -| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | Unary | -| test.cpp:41:9:41:12 | & ... | test.cpp:41:9:41:12 | StoreValue | -| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:10:41:12 | Unary | -| test.cpp:41:10:41:12 | Load | test.cpp:41:10:41:12 | ref | -| test.cpp:41:10:41:12 | Unary | test.cpp:41:9:41:12 | & ... | -| test.cpp:41:10:41:12 | Unary | test.cpp:41:10:41:12 | (reference dereference) | -| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | Unary | -| test.cpp:47:9:47:10 | (reference to) | test.cpp:47:9:47:10 | StoreValue | -| test.cpp:47:9:47:10 | Unary | test.cpp:47:9:47:10 | (reference to) | -| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | Unary | -| test.cpp:54:9:54:15 | & ... | test.cpp:54:9:54:15 | StoreValue | -| test.cpp:54:11:54:12 | Unary | test.cpp:54:14:54:14 | a | -| test.cpp:54:11:54:12 | mc | test.cpp:54:11:54:12 | Unary | -| test.cpp:54:14:54:14 | Unary | test.cpp:54:9:54:15 | & ... | -| test.cpp:54:14:54:14 | a | test.cpp:54:14:54:14 | Unary | -| test.cpp:89:3:89:11 | Store | test.cpp:92:9:92:11 | Load | -| test.cpp:89:9:89:11 | & ... | test.cpp:89:9:89:11 | StoreValue | -| test.cpp:89:9:89:11 | StoreValue | test.cpp:89:3:89:11 | Store | -| test.cpp:89:10:89:11 | Unary | test.cpp:89:9:89:11 | & ... | -| test.cpp:89:10:89:11 | mc | test.cpp:89:10:89:11 | Unary | -| test.cpp:92:9:92:11 | Load | test.cpp:92:9:92:11 | ptr | -| test.cpp:92:9:92:11 | ptr | test.cpp:92:9:92:11 | StoreValue | -| test.cpp:112:9:112:11 | Unary | test.cpp:112:9:112:11 | array to pointer conversion | -| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | Unary | -| test.cpp:112:9:112:11 | array to pointer conversion | test.cpp:112:9:112:11 | StoreValue | -| test.cpp:119:9:119:18 | & ... | test.cpp:119:9:119:18 | StoreValue | -| test.cpp:119:11:119:13 | Left | test.cpp:119:11:119:17 | access to array | -| test.cpp:119:11:119:13 | Unary | test.cpp:119:11:119:13 | array to pointer conversion | -| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | Unary | -| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:13 | Left | -| test.cpp:119:11:119:17 | Unary | test.cpp:119:9:119:18 | & ... | -| test.cpp:119:11:119:17 | access to array | test.cpp:119:11:119:17 | Unary | -| test.cpp:134:2:134:14 | Store | test.cpp:135:2:135:4 | Load | -| test.cpp:134:8:134:10 | Left | test.cpp:134:8:134:14 | ... + ... | -| test.cpp:134:8:134:10 | Unary | test.cpp:134:8:134:10 | array to pointer conversion | -| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | Unary | -| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:10 | Left | -| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:8:134:14 | StoreValue | -| test.cpp:134:8:134:14 | StoreValue | test.cpp:134:2:134:14 | Store | -| test.cpp:135:2:135:4 | Left | test.cpp:135:2:135:6 | PointerAdd | -| test.cpp:135:2:135:4 | Load | test.cpp:135:2:135:4 | ptr | -| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:4 | Left | -| test.cpp:135:2:135:6 | PointerAdd | test.cpp:135:2:135:6 | StoreValue | -| test.cpp:135:2:135:6 | Store | test.cpp:137:9:137:11 | Load | -| test.cpp:135:2:135:6 | StoreValue | test.cpp:135:2:135:6 | Store | -| test.cpp:137:9:137:11 | Load | test.cpp:137:9:137:11 | ptr | -| test.cpp:137:9:137:11 | ptr | test.cpp:137:9:137:11 | StoreValue | -| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | StoreValue | -| test.cpp:170:26:170:41 | Store | test.cpp:171:10:171:23 | Load | -| test.cpp:170:26:170:41 | StoreValue | test.cpp:170:26:170:41 | Store | -| test.cpp:170:34:170:41 | & ... | test.cpp:170:34:170:41 | Unary | -| test.cpp:170:34:170:41 | Unary | test.cpp:170:26:170:41 | (void *)... | -| test.cpp:170:35:170:41 | Unary | test.cpp:170:34:170:41 | & ... | -| test.cpp:170:35:170:41 | myLocal | test.cpp:170:35:170:41 | Unary | -| test.cpp:171:10:171:23 | Load | test.cpp:171:10:171:23 | pointerToLocal | -| test.cpp:171:10:171:23 | pointerToLocal | test.cpp:171:10:171:23 | StoreValue | -| test.cpp:176:25:176:34 | Store | test.cpp:177:10:177:23 | Load | -| test.cpp:176:25:176:34 | StoreValue | test.cpp:176:25:176:34 | Store | -| test.cpp:176:25:176:34 | Unary | test.cpp:176:25:176:34 | array to pointer conversion | -| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | StoreValue | -| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | Unary | -| test.cpp:177:10:177:23 | (void *)... | test.cpp:177:10:177:23 | StoreValue | -| test.cpp:177:10:177:23 | Load | test.cpp:177:10:177:23 | pointerToLocal | -| test.cpp:177:10:177:23 | Unary | test.cpp:177:10:177:23 | (void *)... | -| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | Unary | -| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | StoreValue | -| test.cpp:182:21:182:27 | Store | test.cpp:183:10:183:19 | Load | -| test.cpp:182:21:182:27 | StoreValue | test.cpp:182:21:182:27 | Store | -| test.cpp:182:21:182:27 | Unary | test.cpp:182:21:182:27 | (reference to) | -| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | Unary | -| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | Unary | -| test.cpp:183:10:183:19 | (reference to) | test.cpp:183:10:183:19 | StoreValue | -| test.cpp:183:10:183:19 | Load | test.cpp:183:10:183:19 | refToLocal | -| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference dereference) | -| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference to) | -| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | Unary | -| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | StoreValue | -| test.cpp:189:16:189:16 | Store | test.cpp:190:10:190:13 | Load | -| test.cpp:189:16:189:16 | StoreValue | test.cpp:189:16:189:16 | Store | -| test.cpp:189:16:189:16 | Unary | test.cpp:189:16:189:16 | (reference to) | -| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | Unary | -| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | Unary | -| test.cpp:190:10:190:13 | (reference to) | test.cpp:190:10:190:13 | StoreValue | -| test.cpp:190:10:190:13 | Load | test.cpp:190:10:190:13 | pRef | -| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference dereference) | -| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference to) | -| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | Unary | +| test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | +| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | & ... | +| test.cpp:23:17:23:19 | & ... | test.cpp:25:9:25:11 | ptr | +| test.cpp:23:18:23:19 | mc | test.cpp:23:17:23:19 | & ... | +| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | (reference to) | +| test.cpp:39:17:39:18 | (reference to) | test.cpp:41:10:41:12 | ref | +| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | (reference to) | +| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:9:41:12 | & ... | +| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | (reference dereference) | +| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) | +| test.cpp:54:11:54:12 | mc | test.cpp:54:14:54:14 | a | +| test.cpp:54:14:54:14 | a | test.cpp:54:9:54:15 | & ... | +| test.cpp:89:3:89:11 | ... = ... | test.cpp:92:9:92:11 | ptr | +| test.cpp:89:9:89:11 | & ... | test.cpp:89:3:89:11 | ... = ... | +| test.cpp:89:10:89:11 | mc | test.cpp:89:9:89:11 | & ... | +| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion | +| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | array to pointer conversion | +| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:17 | access to array | +| test.cpp:119:11:119:17 | access to array | test.cpp:119:9:119:18 | & ... | +| test.cpp:134:2:134:14 | ... = ... | test.cpp:135:2:135:4 | ptr | +| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | array to pointer conversion | +| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:14 | ... + ... | +| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:2:134:14 | ... = ... | +| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:6 | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | test.cpp:135:2:135:6 | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | test.cpp:137:9:137:11 | ptr | +| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | (void *)... | +| test.cpp:170:26:170:41 | (void *)... | test.cpp:171:10:171:23 | pointerToLocal | +| test.cpp:170:34:170:41 | & ... | test.cpp:170:26:170:41 | (void *)... | +| test.cpp:170:35:170:41 | myLocal | test.cpp:170:34:170:41 | & ... | +| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | array to pointer conversion | +| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:177:10:177:23 | pointerToLocal | +| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | array to pointer conversion | +| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | (void *)... | +| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | (reference to) | +| test.cpp:182:21:182:27 | (reference to) | test.cpp:183:10:183:19 | refToLocal | +| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | (reference to) | +| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | (reference to) | +| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | (reference dereference) | +| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | (reference to) | +| test.cpp:189:16:189:16 | (reference to) | test.cpp:190:10:190:13 | pRef | +| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) | +| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) | +| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) | nodes | test.cpp:17:9:17:11 | & ... | semmle.label | & ... | -| test.cpp:17:9:17:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:17:10:17:11 | Unary | semmle.label | Unary | | test.cpp:17:10:17:11 | mc | semmle.label | mc | | test.cpp:23:17:23:19 | & ... | semmle.label | & ... | -| test.cpp:23:17:23:19 | Store | semmle.label | Store | -| test.cpp:23:17:23:19 | StoreValue | semmle.label | StoreValue | -| test.cpp:23:18:23:19 | Unary | semmle.label | Unary | +| test.cpp:23:17:23:19 | & ... | semmle.label | & ... | | test.cpp:23:18:23:19 | mc | semmle.label | mc | -| test.cpp:25:9:25:11 | Load | semmle.label | Load | -| test.cpp:25:9:25:11 | StoreValue | semmle.label | StoreValue | | test.cpp:25:9:25:11 | ptr | semmle.label | ptr | | test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) | -| test.cpp:39:17:39:18 | Store | semmle.label | Store | -| test.cpp:39:17:39:18 | StoreValue | semmle.label | StoreValue | -| test.cpp:39:17:39:18 | Unary | semmle.label | Unary | +| test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) | | test.cpp:39:17:39:18 | mc | semmle.label | mc | | test.cpp:41:9:41:12 | & ... | semmle.label | & ... | -| test.cpp:41:9:41:12 | StoreValue | semmle.label | StoreValue | | test.cpp:41:10:41:12 | (reference dereference) | semmle.label | (reference dereference) | -| test.cpp:41:10:41:12 | Load | semmle.label | Load | -| test.cpp:41:10:41:12 | Unary | semmle.label | Unary | -| test.cpp:41:10:41:12 | Unary | semmle.label | Unary | | test.cpp:41:10:41:12 | ref | semmle.label | ref | | test.cpp:47:9:47:10 | (reference to) | semmle.label | (reference to) | -| test.cpp:47:9:47:10 | StoreValue | semmle.label | StoreValue | -| test.cpp:47:9:47:10 | Unary | semmle.label | Unary | | test.cpp:47:9:47:10 | mc | semmle.label | mc | | test.cpp:54:9:54:15 | & ... | semmle.label | & ... | -| test.cpp:54:9:54:15 | StoreValue | semmle.label | StoreValue | -| test.cpp:54:11:54:12 | Unary | semmle.label | Unary | | test.cpp:54:11:54:12 | mc | semmle.label | mc | -| test.cpp:54:14:54:14 | Unary | semmle.label | Unary | | test.cpp:54:14:54:14 | a | semmle.label | a | -| test.cpp:89:3:89:11 | Store | semmle.label | Store | +| test.cpp:89:3:89:11 | ... = ... | semmle.label | ... = ... | | test.cpp:89:9:89:11 | & ... | semmle.label | & ... | -| test.cpp:89:9:89:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:89:10:89:11 | Unary | semmle.label | Unary | | test.cpp:89:10:89:11 | mc | semmle.label | mc | -| test.cpp:92:9:92:11 | Load | semmle.label | Load | -| test.cpp:92:9:92:11 | StoreValue | semmle.label | StoreValue | | test.cpp:92:9:92:11 | ptr | semmle.label | ptr | -| test.cpp:112:9:112:11 | StoreValue | semmle.label | StoreValue | -| test.cpp:112:9:112:11 | Unary | semmle.label | Unary | | test.cpp:112:9:112:11 | arr | semmle.label | arr | | test.cpp:112:9:112:11 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:119:9:119:18 | & ... | semmle.label | & ... | -| test.cpp:119:9:119:18 | StoreValue | semmle.label | StoreValue | -| test.cpp:119:11:119:13 | Left | semmle.label | Left | -| test.cpp:119:11:119:13 | Unary | semmle.label | Unary | | test.cpp:119:11:119:13 | arr | semmle.label | arr | | test.cpp:119:11:119:13 | array to pointer conversion | semmle.label | array to pointer conversion | -| test.cpp:119:11:119:17 | Unary | semmle.label | Unary | | test.cpp:119:11:119:17 | access to array | semmle.label | access to array | -| test.cpp:134:2:134:14 | Store | semmle.label | Store | -| test.cpp:134:8:134:10 | Left | semmle.label | Left | -| test.cpp:134:8:134:10 | Unary | semmle.label | Unary | +| test.cpp:134:2:134:14 | ... = ... | semmle.label | ... = ... | | test.cpp:134:8:134:10 | arr | semmle.label | arr | | test.cpp:134:8:134:10 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:134:8:134:14 | ... + ... | semmle.label | ... + ... | -| test.cpp:134:8:134:14 | StoreValue | semmle.label | StoreValue | -| test.cpp:135:2:135:4 | Left | semmle.label | Left | -| test.cpp:135:2:135:4 | Load | semmle.label | Load | | test.cpp:135:2:135:4 | ptr | semmle.label | ptr | -| test.cpp:135:2:135:6 | PointerAdd | semmle.label | PointerAdd | -| test.cpp:135:2:135:6 | Store | semmle.label | Store | -| test.cpp:135:2:135:6 | StoreValue | semmle.label | StoreValue | -| test.cpp:137:9:137:11 | Load | semmle.label | Load | -| test.cpp:137:9:137:11 | StoreValue | semmle.label | StoreValue | +| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ | +| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ | | test.cpp:137:9:137:11 | ptr | semmle.label | ptr | | test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... | -| test.cpp:170:26:170:41 | Store | semmle.label | Store | -| test.cpp:170:26:170:41 | StoreValue | semmle.label | StoreValue | +| test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... | | test.cpp:170:34:170:41 | & ... | semmle.label | & ... | -| test.cpp:170:34:170:41 | Unary | semmle.label | Unary | -| test.cpp:170:35:170:41 | Unary | semmle.label | Unary | | test.cpp:170:35:170:41 | myLocal | semmle.label | myLocal | -| test.cpp:171:10:171:23 | Load | semmle.label | Load | -| test.cpp:171:10:171:23 | StoreValue | semmle.label | StoreValue | | test.cpp:171:10:171:23 | pointerToLocal | semmle.label | pointerToLocal | -| test.cpp:176:25:176:34 | Store | semmle.label | Store | -| test.cpp:176:25:176:34 | StoreValue | semmle.label | StoreValue | -| test.cpp:176:25:176:34 | Unary | semmle.label | Unary | +| test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:176:25:176:34 | localArray | semmle.label | localArray | | test.cpp:177:10:177:23 | (void *)... | semmle.label | (void *)... | -| test.cpp:177:10:177:23 | Load | semmle.label | Load | -| test.cpp:177:10:177:23 | StoreValue | semmle.label | StoreValue | -| test.cpp:177:10:177:23 | Unary | semmle.label | Unary | | test.cpp:177:10:177:23 | pointerToLocal | semmle.label | pointerToLocal | | test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) | -| test.cpp:182:21:182:27 | Store | semmle.label | Store | -| test.cpp:182:21:182:27 | StoreValue | semmle.label | StoreValue | -| test.cpp:182:21:182:27 | Unary | semmle.label | Unary | +| test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) | | test.cpp:182:21:182:27 | myLocal | semmle.label | myLocal | | test.cpp:183:10:183:19 | (reference dereference) | semmle.label | (reference dereference) | | test.cpp:183:10:183:19 | (reference to) | semmle.label | (reference to) | -| test.cpp:183:10:183:19 | Load | semmle.label | Load | -| test.cpp:183:10:183:19 | StoreValue | semmle.label | StoreValue | -| test.cpp:183:10:183:19 | Unary | semmle.label | Unary | -| test.cpp:183:10:183:19 | Unary | semmle.label | Unary | | test.cpp:183:10:183:19 | refToLocal | semmle.label | refToLocal | | test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) | -| test.cpp:189:16:189:16 | Store | semmle.label | Store | -| test.cpp:189:16:189:16 | StoreValue | semmle.label | StoreValue | -| test.cpp:189:16:189:16 | Unary | semmle.label | Unary | +| test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) | | test.cpp:189:16:189:16 | p | semmle.label | p | | test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) | | test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) | -| test.cpp:190:10:190:13 | Load | semmle.label | Load | -| test.cpp:190:10:190:13 | StoreValue | semmle.label | StoreValue | -| test.cpp:190:10:190:13 | Unary | semmle.label | Unary | -| test.cpp:190:10:190:13 | Unary | semmle.label | Unary | | test.cpp:190:10:190:13 | pRef | semmle.label | pRef | #select -| test.cpp:17:9:17:11 | StoreValue | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc | -| test.cpp:25:9:25:11 | StoreValue | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc | -| test.cpp:41:9:41:12 | StoreValue | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | StoreValue | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc | -| test.cpp:47:9:47:10 | StoreValue | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | StoreValue | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc | -| test.cpp:54:9:54:15 | StoreValue | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | StoreValue | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc | -| test.cpp:92:9:92:11 | StoreValue | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc | -| test.cpp:112:9:112:11 | StoreValue | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr | -| test.cpp:119:9:119:18 | StoreValue | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | StoreValue | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr | -| test.cpp:137:9:137:11 | StoreValue | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr | -| test.cpp:171:10:171:23 | StoreValue | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal | -| test.cpp:177:10:177:23 | StoreValue | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray | -| test.cpp:183:10:183:19 | StoreValue | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | StoreValue | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal | -| test.cpp:190:10:190:13 | StoreValue | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | StoreValue | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p | +| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc | +| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc | +| test.cpp:41:9:41:12 | CopyValue: & ... | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | & ... | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc | +| test.cpp:47:9:47:10 | CopyValue: (reference to) | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc | +| test.cpp:54:9:54:15 | CopyValue: & ... | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | & ... | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc | +| test.cpp:92:9:92:11 | Load: ptr | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | ptr | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc | +| test.cpp:112:9:112:11 | Convert: array to pointer conversion | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr | +| test.cpp:119:9:119:18 | CopyValue: & ... | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | & ... | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr | +| test.cpp:137:9:137:11 | Load: ptr | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | ptr | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr | +| test.cpp:171:10:171:23 | Load: pointerToLocal | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | pointerToLocal | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal | +| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray | +| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal | +| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p | diff --git a/cpp/ql/test/query-tests/Metrics/Dependencies/TestPackage.qll b/cpp/ql/test/query-tests/Metrics/Dependencies/TestPackage.qll index 42ddb58a36f..8332bf3ea7c 100644 --- a/cpp/ql/test/query-tests/Metrics/Dependencies/TestPackage.qll +++ b/cpp/ql/test/query-tests/Metrics/Dependencies/TestPackage.qll @@ -3,10 +3,8 @@ import Metrics.Dependencies.ExternalDependencies /** * Count directories as libraries for testing purposes. */ -class TestPackage extends LibraryElement { - TestPackage() { this instanceof Folder } - - override string getName() { result = this.(Folder).getBaseName() } +class TestPackage extends LibraryElement instanceof Folder { + override string getName() { result = super.getBaseName() } override string getVersion() { result = "1.0" } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected index 28d9a9c82e8..3c9571780d7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected @@ -1,19 +1,8 @@ edges -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | -subpaths nodes -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | semmle.label | ... + ... | | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data | -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data | | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection | +subpaths #select -| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | user input (string read by fgets) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index 51cfc800db6..f4bf42b031f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -1,19 +1,20 @@ edges -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | -| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | -subpaths +| test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | +| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | +| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | nodes | test.c:9:23:9:26 | argv | semmle.label | argv | -| test.c:9:23:9:26 | argv | semmle.label | argv | -| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... | -| test.c:17:11:17:18 | fileName | semmle.label | fileName | -| test.c:17:11:17:18 | fileName | semmle.label | fileName | | test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection | +| test.c:31:22:31:25 | argv | semmle.label | argv | +| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection | +| test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument | +| test.c:38:11:38:18 | fileName indirection | semmle.label | fileName indirection | +| test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument | +| test.c:44:11:44:18 | fileName indirection | semmle.label | fileName indirection | +subpaths #select -| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (argv) | +| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (a command-line argument) | +| test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (a command-line argument) | +| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) | +| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h index fe518804cc8..5b6483480f7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/stdlib.h @@ -11,3 +11,7 @@ FILE *fopen(const char *filename, const char *mode); int sprintf(char *s, const char *format, ...); size_t strlen(const char *s); char *strncat(char *s1, const char *s2, size_t n); +int scanf(const char *format, ...); +void *malloc(size_t size); +double strtod(const char *ptr, char **endptr); +char *getenv(const char *name); diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c index 6c2e2316b24..a11fd73edd7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/test.c @@ -26,5 +26,38 @@ int main(int argc, char** argv) { strncat(fileName+len, fixed, FILENAME_MAX-len-1); fopen(fileName, "wb+"); } + + { + char *fileName = argv[1]; + fopen(fileName, "wb+"); // BAD + } + + { + char fileName[20]; + scanf("%s", fileName); + fopen(fileName, "wb+"); // BAD + } + + { + char *fileName = (char*)malloc(20 * sizeof(char)); + scanf("%s", fileName); + fopen(fileName, "wb+"); // BAD + } + + { + char *aNumber = getenv("A_NUMBER"); + double number = strtod(aNumber, 0); + char fileName[20]; + sprintf(fileName, "/foo/%f", number); + fopen(fileName, "wb+"); // GOOD + } + + { + void read(const char *fileName); + read(argv[1]); // BAD [NOT DETECTED] + } } +void read(char *fileName) { + fopen(fileName, "wb+"); +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected index 5542eac5d3a..20be1550401 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected @@ -163,17 +163,17 @@ subpaths #select | test.cpp:23:12:23:19 | command1 | test.cpp:16:20:16:23 | argv | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:16:20:16:23 | argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument | | test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument | -| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (String read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument | -| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (String read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument | -| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (String read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument | +| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument | +| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument | +| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument | | test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ | | test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | Call | Call | | test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | Call | Call | -| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (String read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument | -| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument | -| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument | -| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | -| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | +| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument | +| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument | +| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument | +| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument | +| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument | +| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument | +| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | +| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected index 2c3e9243cf1..170593664f2 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected @@ -7,42 +7,12 @@ edges | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | -| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | -| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | -| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | -| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | -| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | -| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | -| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | -| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | -| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | -| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 | -| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 | -| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | -| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection | -| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | -| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 | -| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 | -| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection | -| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | -| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | @@ -65,16 +35,11 @@ nodes | tests.c:29:28:29:34 | access to array | semmle.label | access to array | | tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection | | tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion | -| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | -| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection | -| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument | -| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | -| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection | | tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... | @@ -84,11 +49,6 @@ nodes #select | tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | | tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | -| tests.c:31:15:31:23 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | -| tests.c:31:15:31:23 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 | -| tests.c:33:21:33:29 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | -| tests.c:33:21:33:29 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | -| tests.c:33:21:33:29 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 | | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 | | tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp index b11a136ed24..b1245c6ae89 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp @@ -332,4 +332,13 @@ void ptr_diff_case() { char* admin_begin_pos = strstr(user, "ADMIN"); int offset = admin_begin_pos ? user - admin_begin_pos : 0; malloc(offset); // GOOD -} \ No newline at end of file +} + +void equality_barrier() { + int size1 = atoi(getenv("USER")); + int size2 = atoi(getenv("USER")); + + if (size1 == size2) { + int* a = (int*)malloc(size1 * sizeof(int)); // GOOD + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c index 6999795b004..29ab7cc8f25 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/test.c @@ -95,5 +95,12 @@ int main(int argc, char** argv) { } } + // GOOD: check the user input first + int maxConnections3 = atoi(argv[1]); + int maxConnections4 = atoi(argv[1]); + if (maxConnections3 == maxConnections4) { + startServer(maxConnections3 * 1000); + } + return 0; } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected index cece7f64714..23850de9418 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected @@ -6,5 +6,5 @@ nodes | test.cpp:58:25:58:29 | input | semmle.label | input | subpaths #select -| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets | user input (String read by gets) | +| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets | user input (string read by gets) | | test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:54:17:54:20 | argv | user input (a command-line argument) | diff --git a/csharp/.gitignore b/csharp/.gitignore index 0701c11fe1d..a030c9444fe 100644 --- a/csharp/.gitignore +++ b/csharp/.gitignore @@ -11,4 +11,7 @@ csharp.log *.tlog .vs *.user -.vscode/launch.json \ No newline at end of file +.vscode/launch.json + +extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json +extractor-pack \ No newline at end of file diff --git a/csharp/actions/create-extractor-pack/action.yml b/csharp/actions/create-extractor-pack/action.yml new file mode 100644 index 00000000000..43b0ec9c6fe --- /dev/null +++ b/csharp/actions/create-extractor-pack/action.yml @@ -0,0 +1,13 @@ +name: Build C# CodeQL pack +description: Builds the C# CodeQL pack +runs: + using: composite + steps: + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.202 + - name: Build Extractor + shell: bash + run: scripts/create-extractor-pack.sh + working-directory: csharp diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs index 9afe24ed72f..df362c2a129 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs @@ -403,7 +403,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.GetCurrentDirectory = cwd; actions.IsWindows = isWindows; - var options = new AutobuildOptions(actions, Language.CSharp); + var options = new CSharpAutobuildOptions(actions); return new CSharpAutobuilder(actions, options); } @@ -576,7 +576,7 @@ namespace Semmle.Autobuild.CSharp.Tests actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = false; } - private void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun) + private void TestAutobuilderScript(CSharpAutobuilder autobuilder, int expectedOutput, int commandsRun) { Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(actions, StartCallback, EndCallback)); diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj index a91868fbd80..1d5ac39a96f 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj @@ -6,17 +6,17 @@ enable - - - - + + + + all runtime; build; native; contentfiles; analyzers - + - - + + \ No newline at end of file diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs index ff6d2c804cc..71891fa4e8b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs @@ -4,9 +4,32 @@ using Semmle.Autobuild.Shared; namespace Semmle.Autobuild.CSharp { - public class CSharpAutobuilder : Autobuilder + /// + /// Encapsulates C# build options. + /// + public class CSharpAutobuildOptions : AutobuildOptionsShared { - public CSharpAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { } + private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_"; + + public bool Buildless { get; } + + public override Language Language => Language.CSharp; + + + /// + /// Reads options from environment variables. + /// Throws ArgumentOutOfRangeException for invalid arguments. + /// + public CSharpAutobuildOptions(IBuildActions actions) : base(actions) + { + Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) || + actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false); + } + } + + public class CSharpAutobuilder : Autobuilder + { + public CSharpAutobuilder(IBuildActions actions, CSharpAutobuildOptions options) : base(actions, options) { } public override BuildScript GetBuildScript() { diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index 163dbfa1464..394349e2a40 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -13,9 +13,9 @@ namespace Semmle.Autobuild.CSharp /// A build rule where the build command is of the form "dotnet build". /// Currently unused because the tracer does not work with dotnet. /// - internal class DotNetRule : IBuildRule + internal class DotNetRule : IBuildRule { - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (!builder.ProjectsOrSolutionsToBuild.Any()) return BuildScript.Failure; @@ -24,7 +24,7 @@ namespace Semmle.Autobuild.CSharp { var notDotNetProject = builder.ProjectsOrSolutionsToBuild .SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects)) - .OfType() + .OfType>() .FirstOrDefault(p => !p.DotNetProject); if (notDotNetProject is not null) { @@ -56,7 +56,7 @@ namespace Semmle.Autobuild.CSharp }); } - private static BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f) + private static BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) { var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet"); var installScript = DownloadDotNet(builder, installDir); @@ -92,7 +92,7 @@ namespace Semmle.Autobuild.CSharp /// variables needed by the installed .NET Core (null when no variables /// are needed). /// - public static BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f) + public static BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) => WithDotNet(builder, (_1, env) => f(env)); /// @@ -100,7 +100,7 @@ namespace Semmle.Autobuild.CSharp /// .NET Core SDK. The SDK(s) will be installed at installDir /// (provided that the script succeeds). /// - private static BuildScript DownloadDotNet(Autobuilder builder, string installDir) + private static BuildScript DownloadDotNet(IAutobuilder builder, string installDir) { if (!string.IsNullOrEmpty(builder.Options.DotNetVersion)) // Specific version supplied in configuration: always use that @@ -137,7 +137,7 @@ namespace Semmle.Autobuild.CSharp /// /// See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script. /// - private static BuildScript DownloadDotNetVersion(Autobuilder builder, string path, string version) + private static BuildScript DownloadDotNetVersion(IAutobuilder builder, string path, string version) { return BuildScript.Bind(GetInstalledSdksScript(builder.Actions), (sdks, sdksRet) => { @@ -233,7 +233,7 @@ namespace Semmle.Autobuild.CSharp /// /// Gets the `dotnet build` script. /// - private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary? environment, string projOrSln) + private static BuildScript GetBuildScript(IAutobuilder builder, string? dotNetPath, IDictionary? environment, string projOrSln) { var build = new CommandBuilder(builder.Actions, null, environment); var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)). diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs index 2233557af16..479625c76e3 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Program.cs @@ -11,7 +11,7 @@ namespace Semmle.Autobuild.CSharp try { var actions = SystemBuildActions.Instance; - var options = new AutobuildOptions(actions, Language.CSharp); + var options = new CSharpAutobuildOptions(actions); try { Console.WriteLine("CodeQL C# autobuilder"); diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj index 4f712a651d4..981ea925b77 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj @@ -11,15 +11,15 @@ enable - + - - + + - - - + + + \ No newline at end of file diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs index fa6523e37ae..207ecd70f0a 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs @@ -6,9 +6,9 @@ namespace Semmle.Autobuild.CSharp /// /// Build using standalone extraction. /// - internal class StandaloneBuildRule : IBuildRule + internal class StandaloneBuildRule : IBuildRule { - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { BuildScript GetCommand(string? solution) { diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs index ed20bb929ff..d51612272d0 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/AutobuildOptions.cs @@ -6,12 +6,12 @@ using System.Text.RegularExpressions; namespace Semmle.Autobuild.Shared { /// - /// Encapsulates build options. + /// Encapsulates build options shared between C# and C++. /// - public class AutobuildOptions + public abstract class AutobuildOptionsShared { - private const string lgtmPrefix = "LGTM_INDEX_"; - private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_"; + protected const string lgtmPrefix = "LGTM_INDEX_"; + public int SearchDepth { get; } = 3; public string RootDirectory { get; } @@ -25,16 +25,16 @@ namespace Semmle.Autobuild.Shared public string? BuildCommand { get; } public IEnumerable Solution { get; } public bool IgnoreErrors { get; } - public bool Buildless { get; } + public bool AllSolutions { get; } public bool NugetRestore { get; } - public Language Language { get; } + public abstract Language Language { get; } /// /// Reads options from environment variables. /// Throws ArgumentOutOfRangeException for invalid arguments. /// - public AutobuildOptions(IBuildActions actions, Language language) + public AutobuildOptionsShared(IBuildActions actions) { RootDirectory = actions.GetCurrentDirectory(); VsToolsVersion = actions.GetEnvironmentVariable(lgtmPrefix + "VSTOOLS_VERSION"); @@ -48,12 +48,8 @@ namespace Semmle.Autobuild.Shared Solution = actions.GetEnvironmentVariable(lgtmPrefix + "SOLUTION").AsListWithExpandedEnvVars(actions, Array.Empty()); IgnoreErrors = actions.GetEnvironmentVariable(lgtmPrefix + "IGNORE_ERRORS").AsBool("ignore_errors", false); - Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) || - actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false); AllSolutions = actions.GetEnvironmentVariable(lgtmPrefix + "ALL_SOLUTIONS").AsBool("all_solutions", false); NugetRestore = actions.GetEnvironmentVariable(lgtmPrefix + "NUGET_RESTORE").AsBool("nuget_restore", true); - - Language = language; } } diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs index d90175d245a..1ef5ebd815d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Autobuilder.cs @@ -9,21 +9,21 @@ namespace Semmle.Autobuild.Shared /// /// A build rule analyses the files in "builder" and outputs a build script. /// - public interface IBuildRule + public interface IBuildRule where TAutobuildOptions : AutobuildOptionsShared { /// /// Analyse the files and produce a build script. /// /// The files and options relating to the build. /// Whether this build rule is being automatically applied. - BuildScript Analyse(Autobuilder builder, bool auto); + BuildScript Analyse(IAutobuilder builder, bool auto); } /// /// A delegate used to wrap a build script in an environment where an appropriate /// version of .NET Core is automatically installed. /// - public delegate BuildScript WithDotNet(Autobuilder builder, Func?, BuildScript> f); + public delegate BuildScript WithDotNet(IAutobuilder builder, Func?, BuildScript> f) where TAutobuildOptions : AutobuildOptionsShared; /// /// Exception indicating that environment variables are missing or invalid. @@ -33,6 +33,59 @@ namespace Semmle.Autobuild.Shared public InvalidEnvironmentException(string m) : base(m) { } } + public interface IAutobuilder where TAutobuildOptions : AutobuildOptionsShared + { + /// + /// Full file paths of files found in the project directory, as well as + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. + /// + IEnumerable<(string, int)> Paths { get; } + + /// + /// Gets all paths matching a particular filename, as well as + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. + /// + /// The filename to find. + /// Possibly empty sequence of paths with the given filename. + IEnumerable<(string, int)> GetFilename(string name) => + Paths.Where(p => Actions.GetFileName(p.Item1) == name); + + /// + /// List of project/solution files to build. + /// + IList ProjectsOrSolutionsToBuild { get; } + + /// + /// Gets the supplied build configuration. + /// + TAutobuildOptions Options { get; } + + /// + /// The set of build actions used during the autobuilder. + /// Could be real system operations, or a stub for testing. + /// + IBuildActions Actions { get; } + + /// + /// Log a given build event to the console. + /// + /// The format string. + /// Inserts to the format string. + void Log(Severity severity, string format, params object[] args); + + /// + /// Value of CODEQL_EXTRACTOR__ROOT environment variable. + /// + string? CodeQLExtractorLangRoot { get; } + + /// + /// Value of CODEQL_PLATFORM environment variable. + /// + string? CodeQlPlatform { get; } + } + /// /// Main application logic, containing all data /// gathered from the project and filesystem. @@ -40,7 +93,7 @@ namespace Semmle.Autobuild.Shared /// The overall design is intended to be extensible so that in theory, /// it should be possible to add new build rules without touching this code. /// - public abstract class Autobuilder + public abstract class Autobuilder : IAutobuilder where TAutobuildOptions : AutobuildOptionsShared { /// /// Full file paths of files found in the project directory, as well as @@ -60,16 +113,6 @@ namespace Semmle.Autobuild.Shared public IEnumerable<(string, int)> GetExtensions(params string[] extensions) => Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1))); - /// - /// Gets all paths matching a particular filename, as well as - /// their distance from the project root folder. The list is sorted - /// by distance in ascending order. - /// - /// The filename to find. - /// Possibly empty sequence of paths with the given filename. - public IEnumerable<(string, int)> GetFilename(string name) => - Paths.Where(p => Actions.GetFileName(p.Item1) == name); - /// /// Holds if a given path, relative to the root of the source directory /// was found. @@ -115,7 +158,7 @@ namespace Semmle.Autobuild.Shared /// /// Gets the supplied build configuration. /// - public AutobuildOptions Options { get; } + public TAutobuildOptions Options { get; } /// /// The set of build actions used during the autobuilder. @@ -123,7 +166,7 @@ namespace Semmle.Autobuild.Shared /// public IBuildActions Actions { get; } - private IEnumerable? FindFiles(string extension, Func create) + private IEnumerable? FindFiles(string extension, Func> create) { var matchingFiles = GetExtensions(extension) .Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)) @@ -146,7 +189,7 @@ namespace Semmle.Autobuild.Shared /// solution file and tools. /// /// The command line options. - protected Autobuilder(IBuildActions actions, AutobuildOptions options) + protected Autobuilder(IBuildActions actions, TAutobuildOptions options) { Actions = actions; Options = options; @@ -167,7 +210,7 @@ namespace Semmle.Autobuild.Shared foreach (var solution in options.Solution) { if (actions.FileExists(solution)) - ret.Add(new Solution(this, solution, true)); + ret.Add(new Solution(this, solution, true)); else Log(Severity.Error, $"The specified project or solution file {solution} was not found"); } @@ -175,17 +218,17 @@ namespace Semmle.Autobuild.Shared } // First look for `.proj` files - ret = FindFiles(".proj", f => new Project(this, f))?.ToList(); + ret = FindFiles(".proj", f => new Project(this, f))?.ToList(); if (ret is not null) return ret; // Then look for `.sln` files - ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList(); + ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList(); if (ret is not null) return ret; // Finally look for language specific project files, e.g. `.csproj` files - ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList(); + ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList(); return ret ?? new List(); }); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs index b6cb0737630..0d44f0dad4d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandAutoRule.cs @@ -7,11 +7,11 @@ namespace Semmle.Autobuild.Shared /// /// Auto-detection of build scripts. /// - public class BuildCommandAutoRule : IBuildRule + public class BuildCommandAutoRule : IBuildRule { - private readonly WithDotNet withDotNet; + private readonly WithDotNet withDotNet; - public BuildCommandAutoRule(WithDotNet withDotNet) + public BuildCommandAutoRule(WithDotNet withDotNet) { this.withDotNet = withDotNet; } @@ -31,7 +31,7 @@ namespace Semmle.Autobuild.Shared "build" }; - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { builder.Log(Severity.Info, "Attempting to locate build script"); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs index 6db4cfa139d..54d406c9dac 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildCommandRule.cs @@ -3,16 +3,16 @@ /// /// Execute the build_command rule. /// - public class BuildCommandRule : IBuildRule + public class BuildCommandRule : IBuildRule { - private readonly WithDotNet withDotNet; + private readonly WithDotNet withDotNet; - public BuildCommandRule(WithDotNet withDotNet) + public BuildCommandRule(WithDotNet withDotNet) { this.withDotNet = withDotNet; } - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (builder.Options.BuildCommand is null) return BuildScript.Failure; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs index 0afc1da098c..77f2f70f718 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/MsBuildRule.cs @@ -6,14 +6,14 @@ namespace Semmle.Autobuild.Shared /// /// A build rule using msbuild. /// - public class MsBuildRule : IBuildRule + public class MsBuildRule : IBuildRule { /// /// The name of the msbuild command. /// private const string msBuild = "msbuild"; - public BuildScript Analyse(Autobuilder builder, bool auto) + public BuildScript Analyse(IAutobuilder builder, bool auto) { if (!builder.ProjectsOrSolutionsToBuild.Any()) return BuildScript.Failure; @@ -27,8 +27,8 @@ namespace Semmle.Autobuild.Shared { var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType().FirstOrDefault(); vsTools = firstSolution is not null - ? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution) - : BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault(); + ? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution) + : BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault(); } if (vsTools is null && builder.Actions.IsWindows()) @@ -123,7 +123,7 @@ namespace Semmle.Autobuild.Shared /// /// Returns null when no version is specified. /// - public static VcVarsBatFile? GetVcVarsBatFile(Autobuilder builder) + public static VcVarsBatFile? GetVcVarsBatFile(IAutobuilder builder) where TAutobuildOptions : AutobuildOptionsShared { VcVarsBatFile? vsTools = null; @@ -154,7 +154,7 @@ namespace Semmle.Autobuild.Shared /// /// Returns a script for downloading `nuget.exe` from nuget.org. /// - private static BuildScript DownloadNugetExe(Autobuilder builder, string path) => + private static BuildScript DownloadNugetExe(IAutobuilder builder, string path) where TAutobuildOptions : AutobuildOptionsShared => BuildScript.Create(_ => { builder.Log(Severity.Info, "Attempting to download nuget.exe"); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs index bdc712d6623..71522859871 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Project.cs @@ -12,7 +12,7 @@ namespace Semmle.Autobuild.Shared /// C# project files come in 2 flavours, .Net core and msbuild, but they /// have the same file extension. /// - public class Project : ProjectOrSolution + public class Project : ProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared { /// /// Holds if this project is for .Net core. @@ -23,13 +23,13 @@ namespace Semmle.Autobuild.Shared public Version ToolsVersion { get; private set; } - private readonly Lazy> includedProjectsLazy; + private readonly Lazy>> includedProjectsLazy; public override IEnumerable IncludedProjects => includedProjectsLazy.Value; - public Project(Autobuilder builder, string path) : base(builder, path) + public Project(Autobuilder builder, string path) : base(builder, path) { ToolsVersion = new Version(); - includedProjectsLazy = new Lazy>(() => new List()); + includedProjectsLazy = new Lazy>>(() => new List>()); if (!builder.Actions.FileExists(FullPath)) return; @@ -70,9 +70,9 @@ namespace Semmle.Autobuild.Shared } } - includedProjectsLazy = new Lazy>(() => + includedProjectsLazy = new Lazy>>(() => { - var ret = new List(); + var ret = new List>(); // The documentation on `.proj` files is very limited, but it appears that both // `` and `` is valid var mgr = new XmlNamespaceManager(projFile.NameTable); @@ -89,7 +89,7 @@ namespace Semmle.Autobuild.Shared } var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries)); - ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath))); + ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath))); } return ret; }); diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs index 5e4d6c05248..d0c9eeb9669 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/ProjectOrSolution.cs @@ -20,13 +20,13 @@ namespace Semmle.Autobuild.Shared IEnumerable IncludedProjects { get; } } - public abstract class ProjectOrSolution : IProjectOrSolution + public abstract class ProjectOrSolution : IProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared { public string FullPath { get; } public string DirectoryName { get; } - protected ProjectOrSolution(Autobuilder builder, string path) + protected ProjectOrSolution(Autobuilder builder, string path) { FullPath = builder.Actions.GetFullPath(path); DirectoryName = builder.Actions.GetDirectoryName(path) ?? ""; diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj index d3e24dd6ad5..6aceac93f97 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj @@ -8,12 +8,12 @@ enable - + - + - + \ No newline at end of file diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs index 0ec54c1e02f..78929b3a93e 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs @@ -40,11 +40,11 @@ namespace Semmle.Autobuild.Shared /// /// A solution file on the filesystem, read using Microsoft.Build. /// - internal class Solution : ProjectOrSolution, ISolution + internal class Solution : ProjectOrSolution, ISolution where TAutobuildOptions : AutobuildOptionsShared { private readonly SolutionFile? solution; - private readonly IEnumerable includedProjects; + private readonly IEnumerable> includedProjects; public override IEnumerable IncludedProjects => includedProjects; @@ -57,7 +57,7 @@ namespace Semmle.Autobuild.Shared public string DefaultPlatformName => solution is null ? "" : solution.GetDefaultPlatformName(); - public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path) + public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path) { try { @@ -69,19 +69,19 @@ namespace Semmle.Autobuild.Shared // that scenario as a solution with just that one project if (allowProject) { - includedProjects = new[] { new Project(builder, path) }; + includedProjects = new[] { new Project(builder, path) }; return; } builder.Log(Severity.Info, $"Unable to read solution file {path}."); - includedProjects = Array.Empty(); + includedProjects = Array.Empty>(); return; } includedProjects = solution.ProjectsInOrder .Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) .Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries)))) - .Select(p => new Project(builder, p)) + .Select(p => new Project(builder, p)) .ToArray(); } diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index 6ab77f6aba6..d31ce58ff81 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -1,28 +1,28 @@ -package,sink,source,summary,sink:code,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:html,sink:remote,sink:sql,sink:xss,source:file,source:local,summary:taint,summary:value -Dapper,55,,,,,,,,,,55,,,,, -JsonToItemsTaskFactory,,,7,,,,,,,,,,,,7, -Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,28,,,,, -Microsoft.CSharp,,,24,,,,,,,,,,,,24, -Microsoft.EntityFrameworkCore,6,,,,,,,,,,6,,,,, -Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,15, -Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,45,1 -Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,80,3 -Microsoft.Extensions.DependencyInjection,,,62,,,,,,,,,,,,62, -Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,12, -Microsoft.Extensions.FileProviders,,,16,,,,,,,,,,,,16, -Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,,,,,,13,2 -Microsoft.Extensions.Hosting,,,17,,,,,,,,,,,,16,1 -Microsoft.Extensions.Http,,,10,,,,,,,,,,,,10, -Microsoft.Extensions.Logging,,,37,,,,,,,,,,,,37, -Microsoft.Extensions.Options,,,8,,,,,,,,,,,,8, -Microsoft.Extensions.Primitives,,,63,,,,,,,,,,,,63, -Microsoft.Interop,,,27,,,,,,,,,,,,27, -Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,1, -Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,,,,,,4, -Microsoft.VisualBasic,,,10,,,,,,,,,,,,5,5 -Microsoft.Win32,,,8,,,,,,,,,,,,8, -MySql.Data.MySqlClient,48,,,,,,,,,,48,,,,, -Newtonsoft.Json,,,91,,,,,,,,,,,,73,18 -ServiceStack,194,,7,27,,,,,,75,92,,,,7, -System,65,4,12131,,8,8,9,,4,,33,3,1,3,10139,1992 -Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,, +package,sink,source,summary,sink:code,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:html,sink:remote,sink:sql,sink:xss,source:file,source:local,source:remote,summary:taint,summary:value +Dapper,55,,,,,,,,,,55,,,,,, +JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,7, +Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,28,,,,,, +Microsoft.CSharp,,,24,,,,,,,,,,,,,24, +Microsoft.EntityFrameworkCore,6,,,,,,,,,,6,,,,,, +Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,15, +Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,,45,1 +Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,80,3 +Microsoft.Extensions.DependencyInjection,,,62,,,,,,,,,,,,,62, +Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,12, +Microsoft.Extensions.FileProviders,,,16,,,,,,,,,,,,,16, +Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,,,,,,,13,2 +Microsoft.Extensions.Hosting,,,17,,,,,,,,,,,,,16,1 +Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,10, +Microsoft.Extensions.Logging,,,37,,,,,,,,,,,,,37, +Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,8, +Microsoft.Extensions.Primitives,,,63,,,,,,,,,,,,,63, +Microsoft.Interop,,,27,,,,,,,,,,,,,27, +Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,1, +Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,,,,,,,4, +Microsoft.VisualBasic,,,10,,,,,,,,,,,,,5,5 +Microsoft.Win32,,,8,,,,,,,,,,,,,8, +MySql.Data.MySqlClient,48,,,,,,,,,,48,,,,,, +Newtonsoft.Json,,,91,,,,,,,,,,,,,73,18 +ServiceStack,194,,7,27,,,,,,75,92,,,,,7, +System,65,8,12154,,8,8,9,,4,,33,3,1,3,4,10163,1991 +Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,, diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 0f3dce2941a..6324b78ed41 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -8,7 +8,7 @@ C# framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` `ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194, - System,"``System.*``, ``System``",4,12131,65,7 + System,"``System.*``, ``System``",8,12154,65,7 Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,556,138, - Totals,,4,12694,397,7 + Totals,,8,12717,397,7 diff --git a/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/expressions.ql b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/expressions.ql new file mode 100644 index 00000000000..05b9e374f10 --- /dev/null +++ b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/expressions.ql @@ -0,0 +1,13 @@ +class Expression extends @expr { + string toString() { none() } +} + +class TypeOrRef extends @type_or_ref { + string toString() { none() } +} + +from Expression e, int k, int kind, TypeOrRef t +where + expressions(e, k, t) and + if k = [131, 132] then kind = 106 else kind = k +select e, kind, t diff --git a/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/old.dbscheme b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/old.dbscheme new file mode 100644 index 00000000000..83aca6b3e4f --- /dev/null +++ b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/old.dbscheme @@ -0,0 +1,2067 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/semmlecode.csharp.dbscheme b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..4ac7d8bcac6 --- /dev/null +++ b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/semmlecode.csharp.dbscheme @@ -0,0 +1,2064 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/upgrade.properties b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/upgrade.properties new file mode 100644 index 00000000000..f6ae8c489a2 --- /dev/null +++ b/csharp/downgrades/83aca6b3e4fa38dd2b97b9b51dfc199a2ba9c7f2/upgrade.properties @@ -0,0 +1,3 @@ +description: Remove list- and slice pattern expression kinds. +compatibility: backwards +expressions.rel: run expressions.qlo \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj index 8dc6d8a9f76..2d9263eb24e 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj +++ b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -24,7 +24,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj index 5546278e93c..09a36029f13 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj @@ -12,17 +12,17 @@ enable - - + + - + - - - - - + + + + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs index a564d3e7f16..3c4cdcffc0e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs @@ -1,5 +1,5 @@ -using Semmle.Extraction.Entities; using System.IO; +using Semmle.Util; namespace Semmle.Extraction.CSharp.Entities { @@ -11,12 +11,8 @@ namespace Semmle.Extraction.CSharp.Entities public override void Populate(TextWriter trapFile) { trapFile.commentblock(this); - var child = 0; trapFile.commentblock_location(this, Context.CreateLocation(Symbol.Location)); - foreach (var l in Symbol.CommentLines) - { - trapFile.commentblock_child(this, (CommentLine)l, child++); - } + Symbol.CommentLines.ForEach((l, child) => trapFile.commentblock_child(this, l, child)); } public override bool NeedsPopulation => true; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs index 75614d3ad1e..8dd6cd1ee22 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs @@ -39,45 +39,29 @@ namespace Semmle.Extraction.CSharp.Entities trapFile.compilation_assembly(this, assembly); // Arguments - var index = 0; - foreach (var arg in Compilation.Settings.Args) - { - trapFile.compilation_args(this, index++, arg); - } + Compilation.Settings.Args.ForEach((arg, index) => trapFile.compilation_args(this, index, arg)); // Files - index = 0; - foreach (var file in Context.Compilation.SyntaxTrees.Select(tree => File.Create(Context, tree.FilePath))) - { - trapFile.compilation_compiling_files(this, index++, file); - } + Context.Compilation.SyntaxTrees.Select(tree => File.Create(Context, tree.FilePath)).ForEach((file, index) => trapFile.compilation_compiling_files(this, index, file)); // References - index = 0; - foreach (var file in Context.Compilation.References + Context.Compilation.References .OfType() .Where(r => r.FilePath is not null) - .Select(r => File.Create(Context, r.FilePath!))) - { - trapFile.compilation_referencing_files(this, index++, file); - } + .Select(r => File.Create(Context, r.FilePath!)) + .ForEach((file, index) => trapFile.compilation_referencing_files(this, index, file)); // Diagnostics - index = 0; - foreach (var diag in Context.Compilation.GetDiagnostics().Select(d => new Diagnostic(Context, d))) - { - trapFile.diagnostic_for(diag, this, 0, index++); - } + Context.Compilation + .GetDiagnostics() + .Select(d => new Diagnostic(Context, d)) + .ForEach((diag, index) => trapFile.diagnostic_for(diag, this, 0, index)); } public void PopulatePerformance(PerformanceMetrics p) { var trapFile = Context.TrapWriter.Writer; - var index = 0; - foreach (var metric in p.Metrics) - { - trapFile.compilation_time(this, -1, index++, metric); - } + p.Metrics.ForEach((metric, index) => trapFile.compilation_time(this, -1, index, metric)); trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs index c7860d2ad93..345fdd612b3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.Kinds; +using Semmle.Util; using System.Collections.Generic; using System.IO; using System.Linq; @@ -108,11 +109,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions if (length > 0) { var arrayInit = ArrayInitializer.CreateGenerated(cx, arrayCreation, InitializerIndex, location); - var child = 0; - foreach (var item in items) - { - Expression.CreateGenerated(cx, item, arrayInit, child++, location); - } + items.ForEach((item, child) => Expression.CreateGenerated(cx, item, arrayInit, child, location)); } return arrayCreation; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs index 7124929a37c..266c820f68d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs @@ -1,8 +1,8 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; +using Semmle.Util; using System.IO; namespace Semmle.Extraction.CSharp.Entities.Expressions @@ -146,11 +146,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions var init = (InitializerExpressionSyntax)i; - var addChild = 0; - foreach (var arg in init.Expressions) - { - Create(Context, arg, invocation, addChild++); - } + init.Expressions.ForEach((arg, child) => Create(Context, arg, invocation, child)); } else { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs index 2d0292ae720..ec5177c8ce6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; namespace Semmle.Extraction.CSharp.Entities.Expressions diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/ListPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/ListPattern.cs new file mode 100644 index 00000000000..37e19b41aa7 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/ListPattern.cs @@ -0,0 +1,15 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Kinds; +using Semmle.Util; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class ListPattern : Expression + { + internal ListPattern(Context cx, ListPatternSyntax syntax, IExpressionParentEntity parent, int child) : + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.LIST_PATTERN, parent, child, false, null)) + { + syntax.Patterns.ForEach((p, i) => Pattern.Create(cx, p, this, i)); + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs index d883995d062..500154b654d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; -using Semmle.Extraction.Entities; namespace Semmle.Extraction.CSharp.Entities.Expressions { @@ -74,6 +73,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case DiscardPatternSyntax dp: return new Discard(cx, dp, parent, child); + case ListPatternSyntax listPattern: + return new ListPattern(cx, listPattern, parent, child); + + case SlicePatternSyntax slicePattern: + return new SlicePattern(cx, slicePattern, parent, child); + default: throw new InternalError(syntax, "Pattern not handled"); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs index f0ae03ae9dc..53e3dbbacd9 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs @@ -1,6 +1,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.Kinds; -using Semmle.Extraction.Entities; +using Semmle.Util; namespace Semmle.Extraction.CSharp.Entities.Expressions { @@ -9,11 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, null, cx.CreateLocation(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null)) { - child = 0; - foreach (var sub in posPc.Subpatterns) - { - Expressions.Pattern.Create(cx, sub.Pattern, this, child++); - } + posPc.Subpatterns.ForEach((p, i) => Pattern.Create(cx, p.Pattern, this, i)); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs index 1aa515eca2a..30a020702e5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs @@ -1,8 +1,6 @@ -using System; using System.Collections.Generic; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.Kinds; -using Semmle.Extraction.Entities; namespace Semmle.Extraction.CSharp.Entities.Expressions { @@ -27,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions private class AccessStepPack { - public readonly List Prefix = new List(); + public readonly List Prefix = new(); public AccessStep Last { get; private set; } public AccessStepPack Add(string identifier, Microsoft.CodeAnalysis.Location location) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs index d29292b3073..8fa3e8f5f23 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs @@ -2,7 +2,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; using Semmle.Extraction.Kinds; -using Semmle.Extraction.Entities; namespace Semmle.Extraction.CSharp.Entities.Expressions { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs index 471ab5ca48f..e062692cf8f 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs @@ -2,7 +2,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; using Semmle.Extraction.Kinds; -using Semmle.Extraction.Entities; namespace Semmle.Extraction.CSharp.Entities.Expressions { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/SlicePattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/SlicePattern.cs new file mode 100644 index 00000000000..d52af4f54f4 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/SlicePattern.cs @@ -0,0 +1,17 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class SlicePattern : Expression + { + public SlicePattern(Context cx, SlicePatternSyntax syntax, IExpressionParentEntity parent, int child) : + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SLICE_PATTERN, parent, child, false, null)) + { + if (syntax.Pattern is not null) + { + Pattern.Create(cx, syntax.Pattern, this, 0); + } + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs index ce2cf773a92..1703211fb3d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs @@ -1,5 +1,4 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; namespace Semmle.Extraction.CSharp.Entities.Expressions diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs index 0e4ca37a49f..81444206fd7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs @@ -1,6 +1,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Util; using System.IO; namespace Semmle.Extraction.CSharp.Entities @@ -15,12 +16,7 @@ namespace Semmle.Extraction.CSharp.Entities protected override void PopulatePreprocessor(TextWriter trapFile) { trapFile.pragma_warnings(this, Symbol.DisableOrRestoreKeyword.IsKind(SyntaxKind.DisableKeyword) ? 0 : 1); - - var childIndex = 0; - foreach (var code in Symbol.ErrorCodes) - { - trapFile.pragma_warning_error_codes(this, code.ToString(), childIndex++); - } + Symbol.ErrorCodes.ForEach((code, child) => trapFile.pragma_warning_error_codes(this, code.ToString(), child)); } public static PragmaWarningDirective Create(Context cx, PragmaWarningDirectiveTriviaSyntax p) => diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs index 11e54ddff35..536af5065ed 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.IO; using System.Linq; +using System.Text.RegularExpressions; namespace Semmle.Extraction.CSharp.Entities { @@ -162,6 +163,13 @@ namespace Semmle.Extraction.CSharp.Entities operatorName = "false"; break; default: + var match = Regex.Match(methodName, "^op_Checked(.*)$"); + if (match.Success) + { + OperatorSymbol("op_" + match.Groups[1], out var uncheckedName); + operatorName = "checked " + uncheckedName; + break; + } operatorName = methodName; success = false; break; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs index de48df1dc71..a56ccf4c746 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs @@ -125,6 +125,8 @@ namespace Semmle.Extraction.Kinds OR_PATTERN = 128, FUNCTION_POINTER_INVOCATION = 129, WITH = 130, - DEFINE_SYMBOL = 999 + LIST_PATTERN = 131, + SLICE_PATTERN = 132, + DEFINE_SYMBOL = 999, } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj index 77e204997b3..6ef0e4aa1ce 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj @@ -10,15 +10,15 @@ enable - - - + + + - + - - + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj index c4fa93f9697..e75d4c779ae 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj +++ b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj @@ -6,19 +6,19 @@ enable - - - - + + + + all runtime; build; native; contentfiles; analyzers - + - - - - + + + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj index f647003ebf0..b93f3a40043 100644 --- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj +++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj @@ -12,13 +12,13 @@ TRACE;DEBUG;DEBUG_LABELS - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj index 7447a7e82c1..9edca915bd0 100644 --- a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj +++ b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj @@ -6,14 +6,14 @@ enable - - + + all runtime; build; native; contentfiles; analyzers - + - + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Util/IEnumerableExtensions.cs b/csharp/extractor/Semmle.Util/IEnumerableExtensions.cs index 06be296d255..4e40288d88c 100644 --- a/csharp/extractor/Semmle.Util/IEnumerableExtensions.cs +++ b/csharp/extractor/Semmle.Util/IEnumerableExtensions.cs @@ -79,6 +79,19 @@ namespace Semmle.Util a(item); } + /// + /// Applies the action to each item and its index in this collection. + /// + public static void ForEach(this IEnumerable items, Action a) + { + var i = 0; + foreach (var item in items) + { + a(item, i); + i++; + } + } + /// /// Forces enumeration of this collection and discards the result. /// diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 98c13dfaa77..8d5d8f7df35 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 1.3.6 + +No user-facing changes. + +## 1.3.5 + +No user-facing changes. + +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll b/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll index 51559093b07..3d3468af78d 100644 --- a/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll +++ b/csharp/ql/campaigns/Solorigate/lib/Solorigate.qll @@ -1,4 +1,4 @@ -/* +/** * Provides reusable predicates related to Solorigate */ diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.5.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.5.md new file mode 100644 index 00000000000..7f3c47d2ca5 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.5.md @@ -0,0 +1,3 @@ +## 1.3.5 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md new file mode 100644 index 00000000000..ce7baecf210 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.6.md @@ -0,0 +1,3 @@ +## 1.3.6 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index eb1f7dabc84..0a0b0986311 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.6 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index ccab1b3a8b8..3db26da98de 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.3.4-dev +version: 1.4.0-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 98c13dfaa77..8d5d8f7df35 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 1.3.6 + +No user-facing changes. + +## 1.3.5 + +No user-facing changes. + +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.5.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.5.md new file mode 100644 index 00000000000..7f3c47d2ca5 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.5.md @@ -0,0 +1,3 @@ +## 1.3.5 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md new file mode 100644 index 00000000000..ce7baecf210 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.6.md @@ -0,0 +1,3 @@ +## 1.3.6 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index eb1f7dabc84..0a0b0986311 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.6 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 209538a2014..9d3c5a80b02 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.3.4-dev +version: 1.4.0-dev groups: - csharp - solorigate diff --git a/csharp/ql/consistency-queries/SsaConsistency.ql b/csharp/ql/consistency-queries/SsaConsistency.ql index 71f88bf2ab0..225aeb4e6de 100644 --- a/csharp/ql/consistency-queries/SsaConsistency.ql +++ b/csharp/ql/consistency-queries/SsaConsistency.ql @@ -1,8 +1,9 @@ import csharp -import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency as Consistency +import semmle.code.csharp.dataflow.internal.SsaImpl as Impl +import Impl::Consistency import Ssa -class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition { +class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { @@ -10,13 +11,13 @@ class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definit } } -query predicate nonUniqueDef = Consistency::nonUniqueDef/4; - -query predicate readWithoutDef = Consistency::readWithoutDef/3; - -query predicate deadDef = Consistency::deadDef/2; - -query predicate notDominatedByDef = Consistency::notDominatedByDef/4; +class MyRelevantDefinitionExt extends RelevantDefinitionExt, Impl::DefinitionExt { + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) { // Local variables in C# must be initialized before every use, so uninitialized diff --git a/csharp/ql/examples/snippets/catch_exception.ql b/csharp/ql/examples/snippets/catch_exception.ql index eff10ed9ba1..b01ef55da14 100644 --- a/csharp/ql/examples/snippets/catch_exception.ql +++ b/csharp/ql/examples/snippets/catch_exception.ql @@ -10,5 +10,5 @@ import csharp from CatchClause catch -where catch.getCaughtExceptionType().hasQualifiedName("System.IO.IOException") +where catch.getCaughtExceptionType().hasQualifiedName("System.IO", "IOException") select catch diff --git a/csharp/ql/examples/snippets/constructor_call.ql b/csharp/ql/examples/snippets/constructor_call.ql index 0329b13169e..62adb46fbb9 100644 --- a/csharp/ql/examples/snippets/constructor_call.ql +++ b/csharp/ql/examples/snippets/constructor_call.ql @@ -10,5 +10,5 @@ import csharp from ObjectCreation new -where new.getObjectType().hasQualifiedName("System.Exception") +where new.getObjectType().hasQualifiedName("System", "Exception") select new diff --git a/csharp/ql/examples/snippets/extend_class.ql b/csharp/ql/examples/snippets/extend_class.ql index 40a2eeb20d3..00d062b8978 100644 --- a/csharp/ql/examples/snippets/extend_class.ql +++ b/csharp/ql/examples/snippets/extend_class.ql @@ -13,5 +13,5 @@ import csharp from RefType type -where type.getABaseType+().hasQualifiedName("System.Collections.IEnumerator") +where type.getABaseType+().hasQualifiedName("System.Collections", "IEnumerator") select type diff --git a/csharp/ql/examples/snippets/field_read.ql b/csharp/ql/examples/snippets/field_read.ql index e36c92aadf9..ee7dbe17d75 100644 --- a/csharp/ql/examples/snippets/field_read.ql +++ b/csharp/ql/examples/snippets/field_read.ql @@ -11,6 +11,6 @@ import csharp from Field f, FieldRead read where f.hasName("VirtualAddress") and - f.getDeclaringType().hasQualifiedName("Mono.Cecil.PE.Section") and + f.getDeclaringType().hasQualifiedName("Mono.Cecil.PE", "Section") and f = read.getTarget() select read diff --git a/csharp/ql/examples/snippets/method_call.ql b/csharp/ql/examples/snippets/method_call.ql index 8ae3c8d3fb0..723efc8ecb6 100644 --- a/csharp/ql/examples/snippets/method_call.ql +++ b/csharp/ql/examples/snippets/method_call.ql @@ -12,5 +12,5 @@ from MethodCall call, Method method where call.getTarget() = method and method.hasName("MethodName") and - method.getDeclaringType().hasQualifiedName("Company.Class") + method.getDeclaringType().hasQualifiedName("Company", "Class") select call diff --git a/csharp/ql/examples/snippets/null_argument.ql b/csharp/ql/examples/snippets/null_argument.ql index ca1e1516c34..78a6d3c39eb 100644 --- a/csharp/ql/examples/snippets/null_argument.ql +++ b/csharp/ql/examples/snippets/null_argument.ql @@ -17,6 +17,6 @@ where add.hasName("Add") and add.getDeclaringType() .getUnboundDeclaration() - .hasQualifiedName("System.Collections.Generic.ICollection<>") and + .hasQualifiedName("System.Collections.Generic", "ICollection<>") and call.getAnArgument() instanceof NullLiteral select call diff --git a/csharp/ql/examples/snippets/override_method.ql b/csharp/ql/examples/snippets/override_method.ql index ea5c2126f6a..c93b43ace64 100644 --- a/csharp/ql/examples/snippets/override_method.ql +++ b/csharp/ql/examples/snippets/override_method.ql @@ -11,6 +11,6 @@ import csharp from Method override, Method base where base.hasName("ToString") and - base.getDeclaringType().hasQualifiedName("System.Object") and + base.getDeclaringType().hasQualifiedName("System", "Object") and base.getAnOverrider() = override select override diff --git a/csharp/ql/examples/snippets/throw_exception.ql b/csharp/ql/examples/snippets/throw_exception.ql index 94c1615fd21..b737863225b 100644 --- a/csharp/ql/examples/snippets/throw_exception.ql +++ b/csharp/ql/examples/snippets/throw_exception.ql @@ -9,5 +9,5 @@ import csharp from ThrowStmt throw -where throw.getThrownExceptionType().getBaseClass*().hasQualifiedName("System.IO.IOException") +where throw.getThrownExceptionType().getBaseClass*().hasQualifiedName("System.IO", "IOException") select throw diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj index 50852359bb8..a2fd6979adf 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj +++ b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs b/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs new file mode 100644 index 00000000000..e9708d0b5d2 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs @@ -0,0 +1 @@ +Console.WriteLine(args[0]); diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh b/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh new file mode 100644 index 00000000000..e0f0c8dccd3 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh @@ -0,0 +1,2 @@ +cp $PROJECT_TO_BUILD temp.csproj +dotnet build temp.csproj diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto b/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto new file mode 100644 index 00000000000..74abf5c9766 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py b/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py new file mode 100644 index 00000000000..1b49fb18519 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py @@ -0,0 +1,6 @@ +from create_database_utils import * +import os + +os.environ["PROJECT_TO_BUILD"] = "proj.csproj.no_auto" + +run_codeql_database_create([], test_db="default-db", db=None, lang="csharp") diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 2fff5e72443..0dbf4820b2a 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,17 @@ +## 0.4.6 + +No user-facing changes. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +### Minor Analysis Improvements + +* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. + ## 0.4.3 No user-facing changes. diff --git a/csharp/ql/lib/Linq/Helpers.qll b/csharp/ql/lib/Linq/Helpers.qll index a3c5667c8bb..f2368b69242 100644 --- a/csharp/ql/lib/Linq/Helpers.qll +++ b/csharp/ql/lib/Linq/Helpers.qll @@ -19,11 +19,14 @@ private int numStmts(ForeachStmt fes) { } /** Holds if the type's qualified name is "System.Linq.Enumerable" */ -predicate isEnumerableType(ValueOrRefType t) { t.hasQualifiedName("System.Linq.Enumerable") } +predicate isEnumerableType(ValueOrRefType t) { t.hasQualifiedName("System.Linq", "Enumerable") } /** Holds if the type's qualified name starts with "System.Collections.Generic.IEnumerable" */ predicate isIEnumerableType(ValueOrRefType t) { - t.getQualifiedName().matches("System.Collections.Generic.IEnumerable%") + exists(string type | + t.hasQualifiedName("System.Collections.Generic", type) and + type.matches("IEnumerable%") + ) } /** diff --git a/csharp/ql/lib/change-notes/2022-08-24-tcp-udp-sources.md b/csharp/ql/lib/change-notes/2022-08-24-tcp-udp-sources.md new file mode 100644 index 00000000000..f25753c7af4 --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-08-24-tcp-udp-sources.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added tcp/upd sockets as taint sources. diff --git a/csharp/ql/lib/change-notes/2022-11-14-deprecatehasqualifiedname.md b/csharp/ql/lib/change-notes/2022-11-14-deprecatehasqualifiedname.md new file mode 100644 index 00000000000..472fbaaa5a5 --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-11-14-deprecatehasqualifiedname.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `Element::hasQualifiedName/1` has been deprecated. Use `hasQualifiedName/2` or `hasQualifiedName/3` instead. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md b/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..da5a8d8cd9b --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getNameWithoutBrackets` predicate from the `ValueOrRefType` class in `Type.qll`. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-12-08-listpatterns.md b/csharp/ql/lib/change-notes/2022-12-08-listpatterns.md new file mode 100644 index 00000000000..5f11d1bed81 --- /dev/null +++ b/csharp/ql/lib/change-notes/2022-12-08-listpatterns.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* C# 11: Added support for list- and slice patterns in the extractor. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md b/csharp/ql/lib/change-notes/released/0.4.4.md similarity index 72% rename from csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md rename to csharp/ql/lib/change-notes/released/0.4.4.md index 1c9bb14754d..b3d7e2c3be1 100644 --- a/csharp/ql/lib/change-notes/2022-11-09-modelsasdataextensions.md +++ b/csharp/ql/lib/change-notes/released/0.4.4.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. \ No newline at end of file +## 0.4.4 + +### Minor Analysis Improvements + +* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead. diff --git a/csharp/ql/lib/change-notes/released/0.4.5.md b/csharp/ql/lib/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/csharp/ql/lib/change-notes/released/0.4.6.md b/csharp/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll index b7371fafb3e..adb8df80ea6 100644 --- a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll +++ b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll @@ -1,4 +1,4 @@ -/* +/** * Predicates that help detect potential non-cryptographic hash functions * * By themselves, non-cryptographic functions are common and not dangerous diff --git a/csharp/ql/lib/ext/Dapper.model.yml b/csharp/ql/lib/ext/Dapper.model.yml index 949bc007574..e72f3b076a6 100644 --- a/csharp/ql/lib/ext/Dapper.model.yml +++ b/csharp/ql/lib/ext/Dapper.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["Dapper", "SqlMapper", False, "Execute", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - ["Dapper", "SqlMapper", False, "ExecuteAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml b/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml index 6a8b6031825..5b5e2657bfd 100644 --- a/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml +++ b/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml b/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml index 51ae12fe6fa..3928adf0624 100644 --- a/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml +++ b/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.Extensions.Primitives.model.yml b/csharp/ql/lib/ext/Microsoft.Extensions.Primitives.model.yml index a6d867fae01..07e50792787 100644 --- a/csharp/ql/lib/ext/Microsoft.Extensions.Primitives.model.yml +++ b/csharp/ql/lib/ext/Microsoft.Extensions.Primitives.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["Microsoft.Extensions.Primitives", "StringValues", False, "Add", "(System.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["Microsoft.Extensions.Primitives", "StringValues", False, "Add", "(System.String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.VisualBasic.model.yml b/csharp/ql/lib/ext/Microsoft.VisualBasic.model.yml index 3546e3092b3..708f103fdfd 100644 --- a/csharp/ql/lib/ext/Microsoft.VisualBasic.model.yml +++ b/csharp/ql/lib/ext/Microsoft.VisualBasic.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["Microsoft.VisualBasic", "Collection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["Microsoft.VisualBasic", "Collection", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.IEnumerator.Current]", "value", "manual"] diff --git a/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml b/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml index 7f504e87ace..70d849e122a 100644 --- a/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml +++ b/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRow", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRowAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/Newtonsoft.Json.Linq.model.yml b/csharp/ql/lib/ext/Newtonsoft.Json.Linq.model.yml index adeafdce6a3..ae26fd24c43 100644 --- a/csharp/ql/lib/ext/Newtonsoft.Json.Linq.model.yml +++ b/csharp/ql/lib/ext/Newtonsoft.Json.Linq.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["Newtonsoft.Json.Linq", "JArray", False, "get_Item", "(System.Object)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["Newtonsoft.Json.Linq", "JArray", False, "set_Item", "(System.Object,Newtonsoft.Json.Linq.JToken)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/Newtonsoft.Json.model.yml b/csharp/ql/lib/ext/Newtonsoft.Json.model.yml index 8ac9b9c3383..ce7783b5205 100644 --- a/csharp/ql/lib/ext/Newtonsoft.Json.model.yml +++ b/csharp/ql/lib/ext/Newtonsoft.Json.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["Newtonsoft.Json", "JsonConvert", False, "DeserializeAnonymousType<>", "(System.String,T)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["Newtonsoft.Json", "JsonConvert", False, "DeserializeAnonymousType<>", "(System.String,T,Newtonsoft.Json.JsonSerializerSettings)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml b/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml index ee6d27168c4..ea7634bc244 100644 --- a/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeAnd", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeFrom", "(System.String)", "", "Argument[0]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.Redis.model.yml b/csharp/ql/lib/ext/ServiceStack.Redis.model.yml index a48f736d20a..46415828318 100644 --- a/csharp/ql/lib/ext/ServiceStack.Redis.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.Redis.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["ServiceStack.Redis", "IRedisClient", True, "Custom", "(System.Object[])", "", "Argument[0]", "code", "manual"] - ["ServiceStack.Redis", "IRedisClient", True, "ExecCachedLua", "(System.String,System.Func)", "", "Argument[0]", "code", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.model.yml b/csharp/ql/lib/ext/ServiceStack.model.yml index 814e97f7792..988c7f3b8f9 100644 --- a/csharp/ql/lib/ext/ServiceStack.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["ServiceStack", "IOneWayClient", True, "SendAllOneWay", "(System.Collections.Generic.IEnumerable)", "", "Argument[1].Element", "remote", "manual"] - ["ServiceStack", "IOneWayClient", True, "SendOneWay", "(System.Object)", "", "Argument[0]", "remote", "manual"] @@ -80,7 +80,7 @@ extensions: - ["ServiceStack", "ServiceClientBase", True, "Put", "(System.Object)", "", "Argument[0]", "remote", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["ServiceStack", "HttpResult", False, "HttpResult", "(System.Byte[],System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["ServiceStack", "HttpResult", False, "HttpResult", "(System.IO.Stream,System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.CodeDom.model.yml b/csharp/ql/lib/ext/System.CodeDom.model.yml index a078b085a33..281812fc6bc 100644 --- a/csharp/ql/lib/ext/System.CodeDom.model.yml +++ b/csharp/ql/lib/ext/System.CodeDom.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.CodeDom", "CodeNamespaceImportCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Concurrent.model.yml b/csharp/ql/lib/ext/System.Collections.Concurrent.model.yml index d009ec9d122..1de81de635c 100644 --- a/csharp/ql/lib/ext/System.Collections.Concurrent.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Concurrent.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections.Concurrent", "BlockingCollection<>", False, "Add", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Concurrent", "BlockingCollection<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Generic.model.yml b/csharp/ql/lib/ext/System.Collections.Generic.model.yml index 5f87d13015a..3029690b03f 100644 --- a/csharp/ql/lib/ext/System.Collections.Generic.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Generic.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections.Generic", "Dictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections.Generic", "Dictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml index 5bafea13557..b2bd1b6a774 100644 --- a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections.Immutable", "IImmutableDictionary<,>", True, "AddRange", "(System.Collections.Generic.IEnumerable>)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "IImmutableDictionary<,>", True, "Clear", "()", "", "Argument[this].WithoutElement", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.ObjectModel.model.yml b/csharp/ql/lib/ext/System.Collections.ObjectModel.model.yml index 93b88af59bf..b504b034830 100644 --- a/csharp/ql/lib/ext/System.Collections.ObjectModel.model.yml +++ b/csharp/ql/lib/ext/System.Collections.ObjectModel.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections.ObjectModel", "KeyedCollection<,>", False, "get_Item", "(TKey)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.ObjectModel", "ReadOnlyCollection<>", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Specialized.model.yml b/csharp/ql/lib/ext/System.Collections.Specialized.model.yml index 00a09505fca..8456af24f14 100644 --- a/csharp/ql/lib/ext/System.Collections.Specialized.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Specialized.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections.Specialized", "IOrderedDictionary", True, "get_Item", "(System.Int32)", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue", "value", "manual"] - ["System.Collections.Specialized", "IOrderedDictionary", True, "set_Item", "(System.Int32,System.Object)", "", "Argument[0]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.model.yml b/csharp/ql/lib/ext/System.Collections.model.yml index 8a364ee5357..9aa2c2489c9 100644 --- a/csharp/ql/lib/ext/System.Collections.model.yml +++ b/csharp/ql/lib/ext/System.Collections.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Collections", "ArrayList", False, "AddRange", "(System.Collections.ICollection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.ComponentModel.Design.model.yml b/csharp/ql/lib/ext/System.ComponentModel.Design.model.yml index 38a6cd47520..465a7595f60 100644 --- a/csharp/ql/lib/ext/System.ComponentModel.Design.model.yml +++ b/csharp/ql/lib/ext/System.ComponentModel.Design.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.ComponentModel.Design", "DesignerCollection", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.IEnumerator.Current]", "value", "manual"] - ["System.ComponentModel.Design", "DesignerOptionService+DesignerOptionCollection", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.ComponentModel.model.yml b/csharp/ql/lib/ext/System.ComponentModel.model.yml index b20eaa0a871..cdb5ee29993 100644 --- a/csharp/ql/lib/ext/System.ComponentModel.model.yml +++ b/csharp/ql/lib/ext/System.ComponentModel.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.ComponentModel", "AttributeCollection", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.IEnumerator.Current]", "value", "manual"] - ["System.ComponentModel", "ComponentCollection", False, "CopyTo", "(System.ComponentModel.IComponent[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Configuration.Provider.model.yml b/csharp/ql/lib/ext/System.Configuration.Provider.model.yml index 5c5e60f2f88..b532f8cd95a 100644 --- a/csharp/ql/lib/ext/System.Configuration.Provider.model.yml +++ b/csharp/ql/lib/ext/System.Configuration.Provider.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Configuration.Provider", "ProviderCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Configuration.model.yml b/csharp/ql/lib/ext/System.Configuration.model.yml index 457642ab238..cf367cdcaa8 100644 --- a/csharp/ql/lib/ext/System.Configuration.model.yml +++ b/csharp/ql/lib/ext/System.Configuration.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Configuration", "CommaDelimitedStringCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Configuration", "ConfigurationLockCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.Common.model.yml b/csharp/ql/lib/ext/System.Data.Common.model.yml index f85c4aa6712..bc3864d2813 100644 --- a/csharp/ql/lib/ext/System.Data.Common.model.yml +++ b/csharp/ql/lib/ext/System.Data.Common.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Data.Common", "DataColumnMappingCollection", False, "AddRange", "(System.Array)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Data.Common", "DataColumnMappingCollection", False, "AddRange", "(System.Data.Common.DataColumnMapping[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.Entity.model.yml b/csharp/ql/lib/ext/System.Data.Entity.model.yml index 9df471d3489..36eccd9b38d 100644 --- a/csharp/ql/lib/ext/System.Data.Entity.model.yml +++ b/csharp/ql/lib/ext/System.Data.Entity.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.Data.Entity.TransactionalBehavior,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.EntityClient.model.yml b/csharp/ql/lib/ext/System.Data.EntityClient.model.yml index 692c35d352a..16a24580647 100644 --- a/csharp/ql/lib/ext/System.Data.EntityClient.model.yml +++ b/csharp/ql/lib/ext/System.Data.EntityClient.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String,System.Data.EntityClient.EntityConnection)", "", "Argument[0]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.Odbc.model.yml b/csharp/ql/lib/ext/System.Data.Odbc.model.yml index 3bb650739a2..d1f6a24d5fc 100644 --- a/csharp/ql/lib/ext/System.Data.Odbc.model.yml +++ b/csharp/ql/lib/ext/System.Data.Odbc.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.OleDb.model.yml b/csharp/ql/lib/ext/System.Data.OleDb.model.yml index 5acb38217fc..ebe3cc8b157 100644 --- a/csharp/ql/lib/ext/System.Data.OleDb.model.yml +++ b/csharp/ql/lib/ext/System.Data.OleDb.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String,System.Data.OleDb.OleDbConnection)", "", "Argument[0]", "sql", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.SQLite.model.yml b/csharp/ql/lib/ext/System.Data.SQLite.model.yml index cba3abb6d81..d6d1d70e608 100644 --- a/csharp/ql/lib/ext/System.Data.SQLite.model.yml +++ b/csharp/ql/lib/ext/System.Data.SQLite.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "sql", "manual"] @@ -12,7 +12,7 @@ extensions: - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.String,System.Boolean)", "", "Argument[0]", "sql", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.SqlClient.model.yml b/csharp/ql/lib/ext/System.Data.SqlClient.model.yml index 54e0aec4a53..2040e0f9798 100644 --- a/csharp/ql/lib/ext/System.Data.SqlClient.model.yml +++ b/csharp/ql/lib/ext/System.Data.SqlClient.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "sql", "manual"] @@ -11,7 +11,7 @@ extensions: - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.model.yml b/csharp/ql/lib/ext/System.Data.model.yml index 158811616f4..26f650c96a5 100644 --- a/csharp/ql/lib/ext/System.Data.model.yml +++ b/csharp/ql/lib/ext/System.Data.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Data", "ConstraintCollection", False, "Add", "(System.Data.Constraint)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Data", "ConstraintCollection", False, "AddRange", "(System.Data.Constraint[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Diagnostics.model.yml b/csharp/ql/lib/ext/System.Diagnostics.model.yml index 7d3a862cd91..7085f740265 100644 --- a/csharp/ql/lib/ext/System.Diagnostics.model.yml +++ b/csharp/ql/lib/ext/System.Diagnostics.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Diagnostics", "ActivityTagsCollection", False, "ActivityTagsCollection", "(System.Collections.Generic.IEnumerable>)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Diagnostics", "ActivityTagsCollection", False, "ActivityTagsCollection", "(System.Collections.Generic.IEnumerable>)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Dynamic.model.yml b/csharp/ql/lib/ext/System.Dynamic.model.yml index a79b7538213..19e0c6552a9 100644 --- a/csharp/ql/lib/ext/System.Dynamic.model.yml +++ b/csharp/ql/lib/ext/System.Dynamic.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Dynamic", "ExpandoObject", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Dynamic", "ExpandoObject", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.IO.Compression.model.yml b/csharp/ql/lib/ext/System.IO.Compression.model.yml index 57d93bab865..592b2748a0a 100644 --- a/csharp/ql/lib/ext/System.IO.Compression.model.yml +++ b/csharp/ql/lib/ext/System.IO.Compression.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.IO.Compression", "DeflateStream", False, "DeflateStream", "(System.IO.Stream,System.IO.Compression.CompressionLevel)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.IO.Compression", "DeflateStream", False, "DeflateStream", "(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.IO.model.yml b/csharp/ql/lib/ext/System.IO.model.yml index 66513ce96c6..49b0818ef5f 100644 --- a/csharp/ql/lib/ext/System.IO.model.yml +++ b/csharp/ql/lib/ext/System.IO.model.yml @@ -1,12 +1,12 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSourceModel + extensible: sourceModel data: - ["System.IO", "FileStream", False, "FileStream", "", "", "Argument[this]", "file", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.IO", "FileStream", False, "FileStream", "(System.String,System.IO.FileMode)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.IO", "FileStream", False, "FileStream", "(System.String,System.IO.FileMode,System.IO.FileAccess)", "", "Argument[0]", "Argument[this]", "taint", "manual"] @@ -57,7 +57,19 @@ extensions: - ["System.IO", "Stream", True, "Write", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"] - ["System.IO", "Stream", False, "WriteAsync", "(System.Byte[],System.Int32,System.Int32)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"] - ["System.IO", "Stream", True, "WriteAsync", "(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"] - - ["System.IO", "StreamReader", False, "StreamReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream,System.Text.Encoding)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream,System.Text.Encoding,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.IO.FileStreamOptions)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding,System.Boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding,System.Boolean,System.IO.FileStreamOptions)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding,System.Boolean,System.Int32)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.IO", "StringReader", False, "StringReader", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["System.IO", "TextReader", True, "Read", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["System.IO", "TextReader", True, "Read", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Linq.model.yml b/csharp/ql/lib/ext/System.Linq.model.yml index df5fc4d349f..8dd3c81327c 100644 --- a/csharp/ql/lib/ext/System.Linq.model.yml +++ b/csharp/ql/lib/ext/System.Linq.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Linq", "Enumerable", False, "Aggregate<,,>", "(System.Collections.Generic.IEnumerable,TAccumulate,System.Func,System.Func)", "", "Argument[0].Element", "Argument[2].Parameter[1]", "value", "manual"] - ["System.Linq", "Enumerable", False, "Aggregate<,,>", "(System.Collections.Generic.IEnumerable,TAccumulate,System.Func,System.Func)", "", "Argument[1]", "Argument[2].Parameter[0]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Net.Http.Headers.model.yml b/csharp/ql/lib/ext/System.Net.Http.Headers.model.yml index 6a6a44fb18a..79b6b8cf40c 100644 --- a/csharp/ql/lib/ext/System.Net.Http.Headers.model.yml +++ b/csharp/ql/lib/ext/System.Net.Http.Headers.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Net.Http.Headers", "HttpHeaders", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Net.Http.model.yml b/csharp/ql/lib/ext/System.Net.Http.model.yml index d0ecdd4fb6c..0eafc30988a 100644 --- a/csharp/ql/lib/ext/System.Net.Http.model.yml +++ b/csharp/ql/lib/ext/System.Net.Http.model.yml @@ -1,12 +1,12 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Net.Http", "StringContent", False, "StringContent", "", "", "Argument[0]", "xss", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Net.Mail.model.yml b/csharp/ql/lib/ext/System.Net.Mail.model.yml index 92cf36da3b0..5694b634560 100644 --- a/csharp/ql/lib/ext/System.Net.Mail.model.yml +++ b/csharp/ql/lib/ext/System.Net.Mail.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Net.Mail", "MailAddressCollection", False, "Add", "(System.String)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Net.Sockets.model.yml b/csharp/ql/lib/ext/System.Net.Sockets.model.yml new file mode 100644 index 00000000000..950a818e2d8 --- /dev/null +++ b/csharp/ql/lib/ext/System.Net.Sockets.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: sourceModel + data: + - ["System.Net.Sockets", "TcpClient", False, "GetStream", "", "", "ReturnValue", "remote", "manual"] + - ["System.Net.Sockets", "UpdClient", False, "EndReceive", "", "", "ReturnValue", "remote", "manual"] + - ["System.Net.Sockets", "UpdClient", False, "Receive", "", "", "ReturnValue", "remote", "manual"] + - ["System.Net.Sockets", "UpdClient", False, "ReceiveAsync", "", "", "ReturnValue", "remote", "manual"] diff --git a/csharp/ql/lib/ext/System.Net.model.yml b/csharp/ql/lib/ext/System.Net.model.yml index 436391dda39..8e225805c93 100644 --- a/csharp/ql/lib/ext/System.Net.model.yml +++ b/csharp/ql/lib/ext/System.Net.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Net", "Cookie", False, "get_Value", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["System.Net", "CookieCollection", False, "Add", "(System.Net.CookieCollection)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml index 6ccf3138f02..bd28d9168fd 100644 --- a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml +++ b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Runtime.CompilerServices", "ConditionalWeakTable<,>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>", False, "GetAwaiter", "()", "", "Argument[this].SyntheticField[m_configuredTaskAwaiter]", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Security.Cryptography.X509Certificates.model.yml b/csharp/ql/lib/ext/System.Security.Cryptography.X509Certificates.model.yml index 04c27e61279..d15a5b94713 100644 --- a/csharp/ql/lib/ext/System.Security.Cryptography.X509Certificates.model.yml +++ b/csharp/ql/lib/ext/System.Security.Cryptography.X509Certificates.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Security.Cryptography.X509Certificates", "X509Certificate2Collection", False, "Add", "(System.Security.Cryptography.X509Certificates.X509Certificate2)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Security.Cryptography.X509Certificates", "X509Certificate2Collection", False, "AddRange", "(System.Security.Cryptography.X509Certificates.X509Certificate2Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Security.Cryptography.model.yml b/csharp/ql/lib/ext/System.Security.Cryptography.model.yml index 99027d1559b..1a3392074cf 100644 --- a/csharp/ql/lib/ext/System.Security.Cryptography.model.yml +++ b/csharp/ql/lib/ext/System.Security.Cryptography.model.yml @@ -1,14 +1,14 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Security.Cryptography", "SymmetricAlgorithm", True, "CreateDecryptor", "(System.Byte[],System.Byte[])", "", "Argument[0]", "encryption-decryptor", "manual"] - ["System.Security.Cryptography", "SymmetricAlgorithm", True, "CreateEncryptor", "(System.Byte[],System.Byte[])", "", "Argument[0]", "encryption-encryptor", "manual"] - ["System.Security.Cryptography", "SymmetricAlgorithm", True, "set_Key", "(System.Byte[])", "", "Argument[0]", "encryption-keyprop", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Security.Cryptography", "AsnEncodedDataCollection", False, "Add", "(System.Security.Cryptography.AsnEncodedData)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Security.Cryptography", "AsnEncodedDataCollection", False, "CopyTo", "(System.Security.Cryptography.AsnEncodedData[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Security.Permissions.model.yml b/csharp/ql/lib/ext/System.Security.Permissions.model.yml index 742901782b7..d5b9d6436db 100644 --- a/csharp/ql/lib/ext/System.Security.Permissions.model.yml +++ b/csharp/ql/lib/ext/System.Security.Permissions.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Security.Permissions", "KeyContainerPermissionAccessEntryCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Security.Policy.model.yml b/csharp/ql/lib/ext/System.Security.Policy.model.yml index 4d93d0269a3..751aab19877 100644 --- a/csharp/ql/lib/ext/System.Security.Policy.model.yml +++ b/csharp/ql/lib/ext/System.Security.Policy.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Security.Policy", "ApplicationTrustCollection", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Security.Policy", "Evidence", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Text.RegularExpressions.model.yml b/csharp/ql/lib/ext/System.Text.RegularExpressions.model.yml index 131bed81625..e3890031f9e 100644 --- a/csharp/ql/lib/ext/System.Text.RegularExpressions.model.yml +++ b/csharp/ql/lib/ext/System.Text.RegularExpressions.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Text.RegularExpressions", "CaptureCollection", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Text.RegularExpressions", "GroupCollection", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Text.model.yml b/csharp/ql/lib/ext/System.Text.model.yml index 3aab1e14484..f21a34132bd 100644 --- a/csharp/ql/lib/ext/System.Text.model.yml +++ b/csharp/ql/lib/ext/System.Text.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Text", "Encoding", True, "GetBytes", "(System.Char*,System.Int32,System.Byte*,System.Int32)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["System.Text", "Encoding", True, "GetBytes", "(System.Char[])", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Threading.Tasks.model.yml b/csharp/ql/lib/ext/System.Threading.Tasks.model.yml index 73fc8d1c149..efdd211ea21 100644 --- a/csharp/ql/lib/ext/System.Threading.Tasks.model.yml +++ b/csharp/ql/lib/ext/System.Threading.Tasks.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Threading.Tasks", "Task", False, "ContinueWith", "(System.Action,System.Object)", "", "Argument[1]", "Argument[0].Parameter[1]", "value", "manual"] - ["System.Threading.Tasks", "Task", False, "ContinueWith", "(System.Action,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "Argument[0].Parameter[1]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Web.UI.WebControls.model.yml b/csharp/ql/lib/ext/System.Web.UI.WebControls.model.yml index e73e563f31a..1c50d56d5cc 100644 --- a/csharp/ql/lib/ext/System.Web.UI.WebControls.model.yml +++ b/csharp/ql/lib/ext/System.Web.UI.WebControls.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Web.UI.WebControls", "TextBox", False, "get_Text", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Web.model.yml b/csharp/ql/lib/ext/System.Web.model.yml index 998070a6c64..5cf065ec6dd 100644 --- a/csharp/ql/lib/ext/System.Web.model.yml +++ b/csharp/ql/lib/ext/System.Web.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Web", "HttpResponse", False, "BinaryWrite", "", "", "Argument[0]", "html", "manual"] - ["System.Web", "HttpResponse", False, "TransmitFile", "", "", "Argument[0]", "html", "manual"] @@ -9,7 +9,7 @@ extensions: - ["System.Web", "HttpResponse", False, "WriteFile", "", "", "Argument[0]", "html", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Web", "HttpCookie", False, "get_Value", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["System.Web", "HttpCookie", False, "get_Values", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.Xml.Schema.model.yml b/csharp/ql/lib/ext/System.Xml.Schema.model.yml index 6c2c62f8b35..6666d4bf24c 100644 --- a/csharp/ql/lib/ext/System.Xml.Schema.model.yml +++ b/csharp/ql/lib/ext/System.Xml.Schema.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Xml.Schema", "XmlSchemaCollection", False, "Add", "(System.Xml.Schema.XmlSchema)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Xml.Schema", "XmlSchemaCollection", False, "Add", "(System.Xml.Schema.XmlSchemaCollection)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Xml.Serialization.model.yml b/csharp/ql/lib/ext/System.Xml.Serialization.model.yml index 7dfad76ea35..c506aa4c665 100644 --- a/csharp/ql/lib/ext/System.Xml.Serialization.model.yml +++ b/csharp/ql/lib/ext/System.Xml.Serialization.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Xml.Serialization", "XmlAnyElementAttributes", False, "Add", "(System.Xml.Serialization.XmlAnyElementAttribute)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Xml.Serialization", "XmlAnyElementAttributes", False, "CopyTo", "(System.Xml.Serialization.XmlAnyElementAttribute[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Xml.model.yml b/csharp/ql/lib/ext/System.Xml.model.yml index c2c6ab13517..55825304a14 100644 --- a/csharp/ql/lib/ext/System.Xml.model.yml +++ b/csharp/ql/lib/ext/System.Xml.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System.Xml", "XmlAttributeCollection", False, "CopyTo", "(System.Xml.XmlAttribute[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System.Xml", "XmlDocument", False, "Load", "(System.IO.Stream)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/csharp/ql/lib/ext/System.model.yml b/csharp/ql/lib/ext/System.model.yml index 8693948d3de..b0f74507b87 100644 --- a/csharp/ql/lib/ext/System.model.yml +++ b/csharp/ql/lib/ext/System.model.yml @@ -1,14 +1,14 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSourceModel + extensible: sourceModel data: - ["System", "Console", False, "Read", "", "", "ReturnValue", "local", "manual"] - ["System", "Console", False, "ReadKey", "", "", "ReturnValue", "local", "manual"] - ["System", "Console", False, "ReadLine", "", "", "ReturnValue", "local", "manual"] - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["System", "Array", False, "AsReadOnly<>", "(T[])", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System", "Array", False, "Clear", "(System.Array)", "", "Argument[0].WithoutElement", "Argument[0]", "value", "manual"] diff --git a/csharp/ql/lib/ext/Windows.Security.Cryptography.Core.model.yml b/csharp/ql/lib/ext/Windows.Security.Cryptography.Core.model.yml index de9953ea8ef..094826380b4 100644 --- a/csharp/ql/lib/ext/Windows.Security.Cryptography.Core.model.yml +++ b/csharp/ql/lib/ext/Windows.Security.Cryptography.Core.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["Windows.Security.Cryptography.Core", "SymmetricKeyAlgorithmProvider", False, "CreateSymmetricKey", "(Windows.Storage.Streams.IBuffer)", "", "Argument[0]", "encryption-symmetrickey", "manual"] diff --git a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml index a396d121591..f2c4ea2cb29 100644 --- a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml +++ b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml @@ -1,12 +1,11 @@ - # THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. -# Definitions of taint steps in the dotnet_runtime framework. +# Definitions of models for the dotnet_runtime framework. extensions: - addsTo: pack: codeql/csharp-all - extensible: extSinkModel + extensible: sinkModel data: - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql", "generated"] - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql", "generated"] @@ -40,7 +39,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extSummaryModel + extensible: summaryModel data: - ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+CaseInsensitiveDictionaryConverter", false, "Read", "(System.Text.Json.Utf8JsonReader,System.Type,System.Text.Json.JsonSerializerOptions)", "", "Argument[0]", "ReturnValue", "taint", "generated"] - ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItemConverter", false, "Read", "(System.Text.Json.Utf8JsonReader,System.Type,System.Text.Json.JsonSerializerOptions)", "", "Argument[0]", "ReturnValue", "taint", "generated"] @@ -10196,7 +10195,7 @@ extensions: - addsTo: pack: codeql/csharp-all - extensible: extNegativeSummaryModel + extensible: neutralModel data: - ["AssemblyStripper", "AssemblyStripper", "StripAssembly", "(System.String,System.String)", "generated"] - ["Generators", "EventSourceGenerator", "Execute", "(Microsoft.CodeAnalysis.GeneratorExecutionContext)", "generated"] diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index a43762f9433..75d3cd21610 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.4-dev +version: 0.5.0-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/lib/semmle/code/asp/AspNet.qll b/csharp/ql/lib/semmle/code/asp/AspNet.qll index 0666c5eb782..2876043d4ef 100644 --- a/csharp/ql/lib/semmle/code/asp/AspNet.qll +++ b/csharp/ql/lib/semmle/code/asp/AspNet.qll @@ -5,6 +5,7 @@ */ import csharp +private import semmle.code.csharp.commons.QualifiedName /** * An ASP.NET program element. Either an attribute (`AspAttribute`), an open @@ -40,7 +41,7 @@ class AspAttribute extends AspElement, @asp_attribute { } */ class AspOpenTag extends AspElement, @asp_open_tag { /** Either `>` or `/>`, depending on whether it's an empty tag. */ - private string closeAngle() { if isEmpty() then result = "/>" else result = ">" } + private string closeAngle() { if this.isEmpty() then result = "/>" else result = ">" } /** Gets the `i`th attribute of this open tag. */ AspAttribute getAttribute(int i) { asp_tag_attribute(this, i, _, result) } @@ -58,9 +59,9 @@ class AspOpenTag extends AspElement, @asp_open_tag { predicate isEmpty() { asp_tag_isempty(this) } override string toString() { - if hasAttribute() - then result = "<" + getName() + " ..." + closeAngle() - else result = "<" + getName() + closeAngle() + if this.hasAttribute() + then result = "<" + this.getName() + " ..." + this.closeAngle() + else result = "<" + this.getName() + this.closeAngle() } } @@ -75,9 +76,9 @@ class AspOpenTag extends AspElement, @asp_open_tag { */ class AspCloseTag extends AspElement, @asp_close_tag { /** Gets the name of this close tag. */ - string getName() { result = getBody() } + string getName() { result = this.getBody() } - override string toString() { result = "" } + override string toString() { result = "" } } /** @@ -146,44 +147,49 @@ class AspDirective extends AspElement, @asp_directive { string getName() { asp_directive_name(this, result) } /** Holds if this directive has an attribute. */ - predicate hasAttribute() { exists(getAttribute(_)) } + predicate hasAttribute() { exists(this.getAttribute(_)) } override string toString() { - if hasAttribute() - then result = "<%@" + getName() + " ...%>" - else result = "<%@" + getName() + "%>" + if this.hasAttribute() + then result = "<%@" + this.getName() + " ...%>" + else result = "<%@" + this.getName() + "%>" } } /** A quoted string used as an attribute in a tag. */ class AspQuotedString extends AspAttribute, @asp_quoted_string { override string toString() { - if exists(getBody().indexOf("\"")) - then result = "'" + getBody() + "'" - else result = "\"" + getBody() + "\"" + if exists(this.getBody().indexOf("\"")) + then result = "'" + this.getBody() + "'" + else result = "\"" + this.getBody() + "\"" } } /** Arbitrary text. It will be inserted into the document as is. */ class AspText extends AspElement, @asp_text { - override string toString() { result = getBody() } + override string toString() { result = this.getBody() } } /** An XML directive, such as a `DOCTYPE` declaration. */ class AspXmlDirective extends AspElement, @asp_xml_directive { - override string toString() { result = getBody() } + override string toString() { result = this.getBody() } } /** * A 'Page' ASP directive. */ class PageDirective extends AspDirective { - PageDirective() { getName() = "Page" } + PageDirective() { this.getName() = "Page" } /** * Gets the 'CodeBehind' class from which this page inherits. */ - ValueOrRefType getInheritedType() { result.getQualifiedName() = getInheritedTypeQualifiedName() } + ValueOrRefType getInheritedType() { + exists(string qualifier, string type | + result.hasQualifiedName(qualifier, type) and + splitQualifiedName(this.getInheritedTypeQualifiedName(), qualifier, type) + ) + } private string getInheritedTypeQualifiedName() { // Relevant attributes: @@ -192,11 +198,11 @@ class PageDirective extends AspDirective { // provide a fallback namespace if `Inherits` does not have one // - `CodeBehindFile`/`CodeFile`: used by tooling, but not semantically // relevant at runtime - exists(string inherits | inherits = getAttributeByName("Inherits").getBody() | + exists(string inherits | inherits = this.getAttributeByName("Inherits").getBody() | if inherits.indexOf(".") != -1 then result = inherits else - exists(string className | className = getAttributeByName("ClassName").getBody() | + exists(string className | className = this.getAttributeByName("ClassName").getBody() | // take everything up to and including the last . className.prefix(className.indexOf(".", count(className.indexOf(".")) - 1, 0) + 1) + inherits = result @@ -210,7 +216,7 @@ class PageDirective extends AspDirective { */ class CodeBehindFile extends File { CodeBehindFile() { - getExtension() = "aspx" and + this.getExtension() = "aspx" and exists(PageDirective pageDir | pageDir.getLocation().getFile() = this) } @@ -222,5 +228,5 @@ class CodeBehindFile extends File { /** * Gets the 'CodeBehind' class from which this page inherits. */ - ValueOrRefType getInheritedType() { result = getPageDirective().getInheritedType() } + ValueOrRefType getInheritedType() { result = this.getPageDirective().getInheritedType() } } diff --git a/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll b/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll index a17e5327b09..16d556d4d1d 100644 --- a/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll +++ b/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll @@ -4,6 +4,7 @@ private import CIL private import csharp as CS +private import semmle.code.csharp.commons.QualifiedName private newtype ConsistencyCheck = MissingEntityCheck() or @@ -484,9 +485,12 @@ class InvalidOverride extends MethodViolation { } override string getMessage() { - result = - "Overridden method from " + base.getDeclaringType().getQualifiedName() + - " is not in a base type" + exists(string qualifier, string type | + base.getDeclaringType().hasQualifiedName(qualifier, type) + | + result = + "Overridden method from " + getQualifiedName(qualifier, type) + " is not in a base type" + ) } } diff --git a/csharp/ql/lib/semmle/code/cil/Method.qll b/csharp/ql/lib/semmle/code/cil/Method.qll index da1c46b5dfd..4ba193fb01f 100644 --- a/csharp/ql/lib/semmle/code/cil/Method.qll +++ b/csharp/ql/lib/semmle/code/cil/Method.qll @@ -146,7 +146,7 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN /** Holds if this method is a destructor/finalizer. */ predicate isFinalizer() { - this.getOverriddenMethod*().getQualifiedName() = "System.Object.Finalize" + this.getOverriddenMethod*().hasQualifiedName("System", "Object", "Finalize") } /** Holds if this method is an operator. */ @@ -258,7 +258,7 @@ class Setter extends Accessor { /** Holds if this setter is an `init` accessor. */ predicate isInitOnly() { - exists(Type t | t.getQualifiedName() = "System.Runtime.CompilerServices.IsExternalInit" | + exists(Type t | t.hasQualifiedName("System.Runtime.CompilerServices", "IsExternalInit") | this.hasRequiredCustomModifier(t) ) } diff --git a/csharp/ql/lib/semmle/code/cil/Type.qll b/csharp/ql/lib/semmle/code/cil/Type.qll index 7aeaf9a6495..cfe04df8e2d 100644 --- a/csharp/ql/lib/semmle/code/cil/Type.qll +++ b/csharp/ql/lib/semmle/code/cil/Type.qll @@ -4,6 +4,7 @@ import CIL private import dotnet +private import semmle.code.csharp.commons.QualifiedName /** * Something that contains other types. @@ -19,7 +20,7 @@ class TypeContainer extends DotNet::NamedElement, @cil_type_container { /** A namespace. */ class Namespace extends DotNet::Namespace, TypeContainer, @namespace { - override string toString() { result = this.getQualifiedName() } + override string toString() { result = this.getFullName() } override Namespace getParent() { result = this.getParentNamespace() } @@ -52,7 +53,9 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type { override predicate hasQualifiedName(string qualifier, string name) { name = this.getName() and - qualifier = this.getParent().getQualifiedName() + exists(string pqualifier, string pname | this.getParent().hasQualifiedName(pqualifier, pname) | + qualifier = getQualifiedName(pqualifier, pname) + ) } override Location getALocation() { cil_type_location(this.getUnboundDeclaration(), result) } @@ -65,8 +68,7 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type { /** * Holds if this type is a member of the `System` namespace and has the name - * `name`. This is the same as `getQualifiedName() = "System."`, but is - * faster to compute. + * `name`. */ predicate isSystemType(string name) { exists(Namespace system | this.getParent() = system | diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll index 683ee6268aa..2f8fde205fd 100644 --- a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll @@ -47,19 +47,19 @@ private module Cached { } cached - ReadAccess getAFirstRead(Definition def) { + ReadAccess getAFirstReadExt(DefinitionExt def) { exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | - def.definesAt(_, bb1, i1) and - adjacentDefRead(def, bb1, i1, bb2, i2) and + def.definesAt(_, bb1, i1, _) and + adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and result = bb2.getNode(i2) ) } cached - predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) { + predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) { exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | first = bb1.getNode(i1) and - adjacentDefRead(def, bb1, i1, bb2, i2) and + adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and second = bb2.getNode(i2) ) } @@ -68,9 +68,35 @@ private module Cached { Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) } cached - predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) { - lastRefRedef(def, bb, i, next) + predicate lastRefBeforeRedefExt(DefinitionExt def, BasicBlock bb, int i, DefinitionExt next) { + lastRefRedefExt(def, _, bb, i, next) } } import Cached + +private module Deprecated { + private import CIL + + deprecated ReadAccess getAFirstRead(Definition def) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + result = bb2.getNode(i2) + ) + } + + deprecated predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + first = bb1.getNode(i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + second = bb2.getNode(i2) + ) + } + + deprecated predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) { + lastRefRedef(def, bb, i, next) + } +} + +import Deprecated diff --git a/csharp/ql/lib/semmle/code/csharp/Callable.qll b/csharp/ql/lib/semmle/code/csharp/Callable.qll index 0477874eec1..bc8e1294adb 100644 --- a/csharp/ql/lib/semmle/code/csharp/Callable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Callable.qll @@ -7,6 +7,7 @@ import Member import Stmt import Type import exprs.Call +private import commons.QualifiedName private import dotnet private import semmle.code.csharp.ExprOrStmtParent private import semmle.code.csharp.metrics.Complexity @@ -357,6 +358,9 @@ class Constructor extends DotNet::Constructor, Callable, Member, Attributable, @ if this.isStatic() then result = this.getParameter(i) else result = this.getParameter(i - 1) } + /** Holds if this is a constructor without parameters. */ + predicate isParameterless() { this.getNumberOfParameters() = 0 } + override string getUndecoratedName() { result = ".ctor" } } @@ -459,6 +463,11 @@ class Operator extends Callable, Member, Attributable, @operator { super.hasQualifiedName(qualifier, _) and name = this.getFunctionName() } + + override predicate hasQualifiedName(string namespace, string type, string name) { + super.hasQualifiedName(namespace, type, _) and + name = this.getFunctionName() + } } /** A clone method on a record. */ @@ -996,7 +1005,10 @@ class LocalFunction extends Callable, Modifiable, Attributable, @local_function override Callable getEnclosingCallable() { result = this.getStatement().getEnclosingCallable() } override predicate hasQualifiedName(string qualifier, string name) { - qualifier = this.getEnclosingCallable().getQualifiedName() and + exists(string cqualifier, string type | + this.getEnclosingCallable().hasQualifiedName(cqualifier, type) and + qualifier = getQualifiedName(cqualifier, type) + ) and name = this.getName() } diff --git a/csharp/ql/lib/semmle/code/csharp/Generics.qll b/csharp/ql/lib/semmle/code/csharp/Generics.qll index ef3aced9cb9..ee850f25ea3 100644 --- a/csharp/ql/lib/semmle/code/csharp/Generics.qll +++ b/csharp/ql/lib/semmle/code/csharp/Generics.qll @@ -15,6 +15,7 @@ import Location import Namespace +private import commons.QualifiedName private import dotnet private import TypeRef @@ -97,11 +98,18 @@ private string getTypeArgumentsNames(ConstructedGeneric cg) { result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getName(), "," order by i) } -/** Gets the concatenation of the `getQualifiedName()` of type arguments. */ +bindingset[t] +private string getFullName(Type t) { + exists(string qualifier, string name | + t.hasQualifiedName(qualifier, name) and + result = getQualifiedName(qualifier, name) + ) +} + +/** Gets the concatenation of the `getFullName` of type arguments. */ language[monotonicAggregates] private string getTypeArgumentsQualifiedNames(ConstructedGeneric cg) { - result = - strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getQualifiedName(), "," order by i) + result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | getFullName(t), "," order by i) } /** @@ -159,7 +167,7 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric { ) or not exists(this.getDeclaringType()) and - qualifier = this.getNamespace().getQualifiedName() and + qualifier = this.getNamespace().getFullName() and name0 = this.getUndecoratedName() ) } @@ -424,7 +432,7 @@ class ConstructedType extends ValueOrRefType, ConstructedGeneric { ) or not exists(this.getDeclaringType()) and - qualifier = this.getNamespace().getQualifiedName() and + qualifier = this.getNamespace().getFullName() and name0 = this.getUndecoratedName() ) } @@ -594,8 +602,8 @@ class ConstructedMethod extends Method, ConstructedGeneric { result = this.getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">" } - override predicate hasQualifiedName(string qualifier, string name) { - qualifier = this.getDeclaringType().getQualifiedName() and + override predicate hasQualifiedName(string namespace, string type, string name) { + this.getDeclaringType().hasQualifiedName(namespace, type) and name = this.getUndecoratedName() + "<" + getTypeArgumentsQualifiedNames(this) + ">" } diff --git a/csharp/ql/lib/semmle/code/csharp/PrintAst.qll b/csharp/ql/lib/semmle/code/csharp/PrintAst.qll index d179da2e194..8cb59f3b6c8 100644 --- a/csharp/ql/lib/semmle/code/csharp/PrintAst.qll +++ b/csharp/ql/lib/semmle/code/csharp/PrintAst.qll @@ -107,10 +107,10 @@ private ValueOrRefType getAnInterestingBaseType(ValueOrRefType type) { private predicate isInterestingBaseType(ValueOrRefType type, ValueOrRefType base) { not base instanceof ObjectType and - not base.getQualifiedName() = "System.ValueType" and - not base.getQualifiedName() = "System.Delegate" and - not base.getQualifiedName() = "System.MulticastDelegate" and - not base.getQualifiedName() = "System.Enum" and + not base.hasQualifiedName("System", "ValueType") and + not base.hasQualifiedName("System", "Delegate") and + not base.hasQualifiedName("System", "MulticastDelegate") and + not base.hasQualifiedName("System", "Enum") and exists(TypeMention tm | tm.getTarget() = type and tm.getType() = base) } diff --git a/csharp/ql/lib/semmle/code/csharp/Stmt.qll b/csharp/ql/lib/semmle/code/csharp/Stmt.qll index 3ed9468a8d8..6bf826c675d 100644 --- a/csharp/ql/lib/semmle/code/csharp/Stmt.qll +++ b/csharp/ql/lib/semmle/code/csharp/Stmt.qll @@ -75,7 +75,7 @@ class BlockStmt extends Stmt, @block_stmt { /** Holds if this block is the container of the global statements. */ predicate isGlobalStatementContainer() { - this.getEnclosingCallable().hasQualifiedName("Program.
$") + this.getEnclosingCallable().hasQualifiedName("Program", "
$") } override Stmt stripSingletonBlocks() { diff --git a/csharp/ql/lib/semmle/code/csharp/Type.qll b/csharp/ql/lib/semmle/code/csharp/Type.qll index f95ded84771..8bb92c8c86a 100644 --- a/csharp/ql/lib/semmle/code/csharp/Type.qll +++ b/csharp/ql/lib/semmle/code/csharp/Type.qll @@ -56,13 +56,6 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType } * Either a value type (`ValueType`) or a reference type (`RefType`). */ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_or_ref_type { - /** - * DEPRECATED: use `getUndecoratedName()` instead. - * - * Gets the name of this type without `<...>` brackets, in case it is a generic type. - */ - deprecated string getNameWithoutBrackets() { types(this, _, result) } - /** * Holds if this type has the qualified name `qualifier`.`name`. * @@ -76,7 +69,7 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ ) or not exists(this.getDeclaringType()) and - qualifier = this.getNamespace().getQualifiedName() and + qualifier = this.getNamespace().getFullName() and name = this.getUndecoratedName() } @@ -824,13 +817,15 @@ class RecordClass extends RecordType, Class { */ class AnonymousClass extends Class { AnonymousClass() { anonymous_types(this) } + + override string getAPrimaryQlClass() { result = "AnonymousClass" } } /** * The `object` type, `System.Object`. */ class ObjectType extends Class { - ObjectType() { this.hasQualifiedName("System.Object") } + ObjectType() { this.hasQualifiedName("System", "Object") } override string toStringWithTypes() { result = "object" } @@ -841,7 +836,7 @@ class ObjectType extends Class { * The `string` type, `System.String`. */ class StringType extends Class { - StringType() { this.hasQualifiedName("System.String") } + StringType() { this.hasQualifiedName("System", "String") } override string toStringWithTypes() { result = "string" } diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll index df8ae6ea6ed..f35b10ac934 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll @@ -368,40 +368,32 @@ private Stmt getAnAssertingStmt(Assertion a) { } /** A method that forwards to a Boolean assertion method. */ -class ForwarderBooleanAssertMethod extends BooleanAssertMethod { - private ForwarderAssertMethod forwarder; +class ForwarderBooleanAssertMethod extends BooleanAssertMethod instanceof ForwarderAssertMethod { private BooleanAssertMethod underlying; - ForwarderBooleanAssertMethod() { - forwarder = this and - underlying = forwarder.getUnderlyingAssertMethod() - } + ForwarderBooleanAssertMethod() { underlying = super.getUnderlyingAssertMethod() } override int getAnAssertionIndex(boolean b) { - forwarder.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) + super.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) } override AssertionFailure getAssertionFailure(int i) { - result = underlying.getAssertionFailure(forwarder.getAForwarderAssertionIndex(i)) + result = underlying.getAssertionFailure(super.getAForwarderAssertionIndex(i)) } } /** A method that forwards to a nullness assertion method. */ -class ForwarderNullnessAssertMethod extends NullnessAssertMethod { - private ForwarderAssertMethod forwarder; +class ForwarderNullnessAssertMethod extends NullnessAssertMethod instanceof ForwarderAssertMethod { private NullnessAssertMethod underlying; - ForwarderNullnessAssertMethod() { - forwarder = this and - underlying = forwarder.getUnderlyingAssertMethod() - } + ForwarderNullnessAssertMethod() { underlying = super.getUnderlyingAssertMethod() } override int getAnAssertionIndex(boolean b) { - forwarder.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) + super.getAForwarderAssertionIndex(result) = underlying.getAnAssertionIndex(b) } override AssertionFailure getAssertionFailure(int i) { - result = underlying.getAssertionFailure(forwarder.getAForwarderAssertionIndex(i)) + result = underlying.getAssertionFailure(super.getAForwarderAssertionIndex(i)) } } diff --git a/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll b/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll index 7da80a79ffd..4a90c121e2e 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll @@ -39,7 +39,7 @@ class GeneratedAttributeFile extends GeneratedCodeFile { class GeneratedNamespaceFile extends GeneratedCodeFile { GeneratedNamespaceFile() { exists(Namespace n | n.getATypeDeclaration().getFile() = this | - n.getQualifiedName() = "Microsoft.Xml.Serialization.GeneratedAssembly" + n.getFullName() = "Microsoft.Xml.Serialization.GeneratedAssembly" ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/commons/QualifiedName.qll b/csharp/ql/lib/semmle/code/csharp/commons/QualifiedName.qll new file mode 100644 index 00000000000..4955d8db8f2 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/commons/QualifiedName.qll @@ -0,0 +1,34 @@ +/** + * Provides predicates related to C# qualified names. + */ + +/** + * Returns the concatenation of `qualifier` and `name`, separated by a dot. + */ +bindingset[qualifier, name] +string getQualifiedName(string qualifier, string name) { + if qualifier = "" then result = name else result = qualifier + "." + name +} + +/** + * Returns the concatenation of `namespace`, `type` and `name`, separated by a dot. + */ +bindingset[namespace, type, name] +string getQualifiedName(string namespace, string type, string name) { + result = getQualifiedName(namespace, type) + "." + name +} + +/** + * Holds if `qualifiedName` is the concatenation of `qualifier` and `name`, separated by a dot. + */ +bindingset[qualifiedName] +predicate splitQualifiedName(string qualifiedName, string qualifier, string name) { + exists(string nameSplitter | nameSplitter = "(.*)\\.([^\\.]+)$" | + qualifier = qualifiedName.regexpCapture(nameSplitter, 1) and + name = qualifiedName.regexpCapture(nameSplitter, 2) + or + not qualifiedName.regexpMatch(nameSplitter) and + qualifier = "" and + name = qualifiedName + ) +} diff --git a/csharp/ql/lib/semmle/code/csharp/commons/TargetFramework.qll b/csharp/ql/lib/semmle/code/csharp/commons/TargetFramework.qll index 83de1b9d294..41ce7b36944 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/TargetFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/TargetFramework.qll @@ -14,7 +14,7 @@ class TargetFrameworkAttribute extends Attribute { Assembly assembly; TargetFrameworkAttribute() { - this.getType().getQualifiedName() = "System.Runtime.Versioning.TargetFrameworkAttribute" and + this.getType().hasQualifiedName("System.Runtime.Versioning", "TargetFrameworkAttribute") and assembly = this.getTarget() } diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Util.qll b/csharp/ql/lib/semmle/code/csharp/commons/Util.qll index 342ab2afd4e..91903a9109b 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Util.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Util.qll @@ -8,7 +8,7 @@ class MainMethod extends Method { ( this.hasName("Main") or - this.hasQualifiedName("Program.
$") + this.hasQualifiedName("Program", "
$") ) and this.isStatic() and (this.getReturnType() instanceof VoidType or this.getReturnType() instanceof IntType) and diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll index bda14e0b4ae..cf72b9a6991 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll @@ -103,7 +103,6 @@ abstract class Completion extends TCompletion { * otherwise it is a normal non-Boolean completion. */ predicate isValidFor(ControlFlowElement cfe) { - cfe instanceof NonReturningCall and this = cfe.(NonReturningCall).getACompletion() or this = TThrowCompletion(cfe.(TriedControlFlowElement).getAThrownException()) @@ -199,6 +198,17 @@ private predicate isBooleanConstant(Expr e, boolean value) { value = false or isConstantComparison(e, value) + or + exists(Method m, Call c, Expr expr | + m = any(SystemStringClass s).getIsNullOrEmptyMethod() and + c.getTarget() = m and + e = c and + expr = c.getArgument(0) and + expr.hasValue() and + if expr.getValue().length() > 0 and not expr instanceof NullLiteral + then value = false + else value = true + ) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll index 6bd0d5d033f..37fc97903e6 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll @@ -768,7 +768,7 @@ module Expressions { nc.getOuterCompletion() .(ThrowCompletion) .getExceptionClass() - .hasQualifiedName("System.InvalidOperationException") + .hasQualifiedName("System", "InvalidOperationException") ) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll index dbd90ba0ae1..5039d09ff22 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll @@ -907,9 +907,13 @@ module TestOutput { query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) { attr = "semmle.label" and - exists(SuccessorType t | succ = getASuccessor(pred, t) | - if successorTypeIsSimple(t) then val = "" else val = t.toString() - ) + val = + strictconcat(SuccessorType t, string s | + succ = getASuccessor(pred, t) and + if successorTypeIsSimple(t) then s = "" else s = t.toString() + | + s, ", " order by s + ) or attr = "semmle.order" and val = diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/NonReturning.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/NonReturning.qll index fe9f1148a6d..1f00343e08a 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/NonReturning.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/NonReturning.qll @@ -51,7 +51,7 @@ private class ThrowingCall extends NonReturningCall { this = any(MethodCall mc | mc.getTarget() - .hasQualifiedName("System.Runtime.ExceptionServices.ExceptionDispatchInfo", "Throw") and + .hasQualifiedName("System.Runtime.ExceptionServices", "ExceptionDispatchInfo", "Throw") and ( mc.hasNoArguments() and c.getExceptionClass() instanceof SystemExceptionClass @@ -85,8 +85,8 @@ private class DirectlyExitingCallable extends ExitingCallable { DirectlyExitingCallable() { this = any(Method m | - m.hasQualifiedName("System.Environment", "Exit") or - m.hasQualifiedName("System.Windows.Forms.Application", "Exit") + m.hasQualifiedName("System", "Environment", "Exit") or + m.hasQualifiedName("System.Windows.Forms", "Application", "Exit") ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 874bd51a9f3..dda86ebcd91 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -11,9 +11,9 @@ * `namespace; type; subtypes; name; signature; ext; input; kind; provenance` * - Summaries: * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance` - * - Negative Summaries: + * - Neutrals: * `namespace; type; name; signature; provenance` - * A negative summary is used to indicate that there is no flow via a callable. + * A neutral is used to indicate that there is no flow via a callable. * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. @@ -82,6 +82,7 @@ */ import csharp +private import ExternalFlowExtensions as Extensions private import internal.AccessPathSyntax private import internal.DataFlowDispatch private import internal.DataFlowPrivate @@ -90,43 +91,6 @@ private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific -/** - * A module importing the frameworks that provide external flow data, - * ensuring that they are visible to the taint tracking / data flow library. - */ -private module Frameworks { - private import semmle.code.csharp.frameworks.EntityFramework - private import semmle.code.csharp.frameworks.JsonNET - private import semmle.code.csharp.frameworks.ServiceStack - private import semmle.code.csharp.frameworks.Sql - private import semmle.code.csharp.frameworks.System - private import semmle.code.csharp.frameworks.system.CodeDom - private import semmle.code.csharp.frameworks.system.Collections - private import semmle.code.csharp.frameworks.system.collections.Generic - private import semmle.code.csharp.frameworks.system.collections.Specialized - private import semmle.code.csharp.frameworks.system.Data - private import semmle.code.csharp.frameworks.system.data.Common - private import semmle.code.csharp.frameworks.system.Diagnostics - private import semmle.code.csharp.frameworks.system.Linq - private import semmle.code.csharp.frameworks.system.Net - private import semmle.code.csharp.frameworks.system.net.Mail - private import semmle.code.csharp.frameworks.system.IO - private import semmle.code.csharp.frameworks.system.io.Compression - private import semmle.code.csharp.frameworks.system.runtime.CompilerServices - private import semmle.code.csharp.frameworks.system.Security - private import semmle.code.csharp.frameworks.system.security.Cryptography - private import semmle.code.csharp.frameworks.system.security.cryptography.X509Certificates - private import semmle.code.csharp.frameworks.system.Text - private import semmle.code.csharp.frameworks.system.text.RegularExpressions - private import semmle.code.csharp.frameworks.system.threading.Tasks - private import semmle.code.csharp.frameworks.system.Web - private import semmle.code.csharp.frameworks.system.web.ui.WebControls - private import semmle.code.csharp.frameworks.system.Xml - private import semmle.code.csharp.security.dataflow.flowsinks.Html - private import semmle.code.csharp.security.dataflow.flowsources.Local - private import semmle.code.csharp.security.dataflow.XSSSinks -} - /** * DEPRECATED: Define source models as data extensions instead. * @@ -169,38 +133,12 @@ private class SummaryModelCsvInternal extends Unit { abstract predicate row(string row); } -/** - * DEPRECATED: Define negative summary models as data extensions instead. - * - * A unit class for adding additional negative summary model rows. - * - * Extend this class to add additional negative summary definitions. - */ -deprecated class NegativeSummaryModelCsv = NegativeSummaryModelCsvInternal; - -private class NegativeSummaryModelCsvInternal extends Unit { - /** Holds if `row` specifies a negative summary definition. */ - abstract predicate row(string row); -} - private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) } private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) } private predicate sinkModelInternal(string row) { any(SinkModelCsvInternal s).row(row) } -private predicate negativeSummaryModelInternal(string row) { - any(NegativeSummaryModelCsvInternal s).row(row) -} - -/** - * Holds if a source model exists for the given parameters. - */ -extensible predicate extSourceModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, - string output, string kind, string provenance -); - /** Holds if a source model exists for the given parameters. */ predicate sourceModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, @@ -220,15 +158,9 @@ predicate sourceModel( row.splitAt(";", 8) = provenance ) or - extSourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) + Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) } -/** Holds if a sink model exists for the given parameters. */ -extensible predicate extSinkModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string kind, string provenance -); - /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, @@ -248,15 +180,9 @@ predicate sinkModel( row.splitAt(";", 8) = provenance ) or - extSinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) + Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) } -/** Holds if a summary model exists for the given parameters. */ -extensible predicate extSummaryModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind, string provenance -); - /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, @@ -277,29 +203,12 @@ predicate summaryModel( row.splitAt(";", 9) = provenance ) or - extSummaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) + Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, + provenance) } -/** Holds if a summary model exists indicating there is no flow for the given parameters. */ -extensible predicate extNegativeSummaryModel( - string namespace, string type, string name, string signature, string provenance -); - -/** Holds if a summary model exists indicating there is no flow for the given parameters. */ -predicate negativeSummaryModel( - string namespace, string type, string name, string signature, string provenance -) { - exists(string row | - negativeSummaryModelInternal(row) and - row.splitAt(";", 0) = namespace and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = name and - row.splitAt(";", 3) = signature and - row.splitAt(";", 4) = provenance - ) - or - extNegativeSummaryModel(namespace, type, name, signature, provenance) -} +/** Holds if a model exists indicating there is no flow for the given parameters. */ +predicate neutralModel = Extensions::neutralModel/5; private predicate relevantNamespace(string namespace) { sourceModel(namespace, _, _, _, _, _, _, _, _) or @@ -402,7 +311,7 @@ module ModelValidation { ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["local", "file"] and + not kind = ["local", "remote", "file"] and result = "Invalid kind \"" + kind + "\" in source model." ) } @@ -430,8 +339,6 @@ module ModelValidation { sinkModelInternal(row) and expect = 9 and pred = "sink" or summaryModelInternal(row) and expect = 10 and pred = "summary" - or - negativeSummaryModelInternal(row) and expect = 5 and pred = "negative summary" | exists(int cols | cols = 1 + max(int n | exists(row.splitAt(";", n))) and @@ -455,9 +362,9 @@ module ModelValidation { summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and pred = "summary" or - negativeSummaryModel(namespace, type, name, signature, provenance) and + neutralModel(namespace, type, name, signature, provenance) and ext = "" and - pred = "negative summary" + pred = "neutral" | not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." @@ -498,7 +405,7 @@ private predicate elementSpec( or summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or - negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false + neutralModel(namespace, type, name, signature, _) and ext = "" and subtypes = false } private predicate elementSpec( @@ -632,7 +539,7 @@ private Element interpretElement0( ) } -/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */ +/** Gets the source/sink/summary/neutral element corresponding to the supplied parameters. */ Element interpretElement( string namespace, string type, boolean subtypes, string name, string signature, string ext ) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlowExtensions.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlowExtensions.qll new file mode 100644 index 00000000000..aab3d67e620 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlowExtensions.qll @@ -0,0 +1,34 @@ +/** + * This module provides extensible predicates for defining MaD models. + */ + +/** + * Holds if a source model exists for the given parameters. + */ +extensible predicate sourceModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance +); + +/** + * Holds if a sink model exists for the given parameters. + */ +extensible predicate sinkModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance +); + +/** + * Holds if a summary model exists for the given parameters. + */ +extensible predicate summaryModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance +); + +/** + * Holds if a model exists indicating there is no flow for the given parameters. + */ +extensible predicate neutralModel( + string namespace, string type, string name, string signature, string provenance +); diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll index f377d94e15c..8764da0a784 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll @@ -138,25 +138,6 @@ module Ssa { } } - private string getSplitString(Definition def) { - exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn | - def.definesAt(_, bb, i) and - result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString() - | - cfn = bb.getNode(i) - or - not exists(bb.getNode(i)) and - cfn = bb.getFirstNode() - ) - } - - private string getToStringPrefix(Definition def) { - result = "[" + getSplitString(def) + "] " - or - not exists(getSplitString(def)) and - result = "" - } - /** * A static single assignment (SSA) definition. Either an explicit variable * definition (`ExplicitDefinition`), an implicit variable definition @@ -521,8 +502,8 @@ module Ssa { override string toString() { if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition - then result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")" - else result = getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")" + then result = SsaImpl::getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")" + else result = SsaImpl::getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = ad.getLocation() } @@ -570,8 +551,12 @@ module Ssa { override string toString() { if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable - then result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")" - else result = getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")" + then + result = + SsaImpl::getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")" + else + result = + SsaImpl::getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getCallable().getLocation() } @@ -612,7 +597,7 @@ module Ssa { } override string toString() { - result = getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")" + result = SsaImpl::getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getCall().getLocation() } @@ -640,7 +625,8 @@ module Ssa { final Definition getQualifierDefinition() { result = q } override string toString() { - result = getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")" + result = + SsaImpl::getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getQualifierDefinition().getLocation() } @@ -682,7 +668,7 @@ module Ssa { } override string toString() { - result = getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")" + result = SsaImpl::getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")" } /* diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll index 2bdb56b2aa6..787f2f614f7 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll @@ -222,18 +222,14 @@ module ContentDataFlow { ) } - private class ConfigurationAdapter extends DF::Configuration { - private Configuration c; - - ConfigurationAdapter() { this = c } - + private class ConfigurationAdapter extends DF::Configuration instanceof Configuration { final override predicate isSource(Node source, DF::FlowState state) { - c.isSource(source) and + Configuration.super.isSource(source) and state.(InitState).decode(true) } final override predicate isSink(Node sink, DF::FlowState state) { - c.isSink(sink) and + Configuration.super.isSink(sink) and ( state instanceof InitState or state instanceof StoreState or @@ -249,9 +245,9 @@ module ContentDataFlow { additionalStep(node1, state1, node2, state2, this) } - final override predicate isBarrier(Node node) { c.isBarrier(node) } + final override predicate isBarrier(Node node) { Configuration.super.isBarrier(node) } - final override FlowFeature getAFeature() { result = c.getAFeature() } + final override FlowFeature getAFeature() { result = Configuration.super.getAFeature() } // needed to record reads/stores inside summarized callables final override predicate includeHiddenNodes() { any() } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index 594cbe20865..a6142ce11ee 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -6,7 +6,6 @@ private import DataFlowPublic private import DataFlowPrivate private import FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.dispatch.RuntimeCallable private import semmle.code.csharp.frameworks.system.Collections diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9aa6a529a5b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -915,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -1304,6 +1343,113 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; @@ -1336,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } } @@ -1350,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1362,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll index dde16ab5a2a..e85e0cd92ec 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll @@ -136,6 +136,18 @@ module Consistency { msg = "Local flow step does not preserve enclosing callable." } + query predicate readStepIsLocal(Node n1, Node n2, string msg) { + readStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Read step does not preserve enclosing callable." + } + + query predicate storeStepIsLocal(Node n1, Node n2, string msg) { + storeStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Store step does not preserve enclosing callable." + } + private DataFlowType typeRepr() { result = getNodeType(_) } query predicate compatibleTypesReflexive(DataFlowType t, string msg) { @@ -232,4 +244,25 @@ module Consistency { not callable = viableCallable(call) and not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) } + + query predicate uniqueParameterNodeAtPosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and + msg = "Parameters with overlapping positions." + } + + query predicate uniqueParameterNodePosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and + msg = "Parameter node with multiple positions." + } + + query predicate uniqueContentApprox(Content c, string msg) { + not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and + msg = "Non-unique content approximation." + } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 4fc2cb4f398..e69f7cf6b90 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -18,6 +18,7 @@ private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.system.Collections private import semmle.code.csharp.frameworks.system.threading.Tasks private import semmle.code.cil.Ssa::Ssa as CilSsa +private import semmle.code.cil.internal.SsaImpl as CilSsaImpl /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() } @@ -174,7 +175,7 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No cfn = n1.getControlFlowNode() and ssaDef.getADefinition() = def and ssaDef.getControlFlowNode() = cfnDef and - n2.(SsaDefinitionNode).getDefinition() = ssaDef + n2.(SsaDefinitionExtNode).getDefinitionExt() = ssaDef ) } @@ -306,17 +307,28 @@ module LocalFlow { } } + /** An SSA definition into which another SSA definition may flow. */ + private class SsaInputDefinitionExtNode extends SsaDefinitionExtNode { + SsaInputDefinitionExtNode() { + def instanceof Ssa::PhiNode + or + def instanceof SsaImpl::PhiReadNode + or + def instanceof LocalFlow::UncertainExplicitSsaDefinition + } + } + /** * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which * can reach `next`. */ private predicate localFlowSsaInputFromDef( - Node nodeFrom, Ssa::Definition def, Ssa::Definition next + Node nodeFrom, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next ) { exists(ControlFlow::BasicBlock bb, int i | - SsaImpl::lastRefBeforeRedef(def, bb, i, next) and - def.definesAt(_, bb, i) and - def = getSsaDefinition(nodeFrom) + SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and + def.definesAt(_, bb, i, _) and + def = getSsaDefinitionExt(nodeFrom) ) } @@ -324,18 +336,17 @@ module LocalFlow { * Holds if `read` is a last node reading SSA definition `def`, which * can reach `next`. */ - predicate localFlowSsaInputFromExpr( - ControlFlow::Node read, Ssa::Definition def, Ssa::Definition next + predicate localFlowSsaInputFromRead( + Node read, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next ) { exists(ControlFlow::BasicBlock bb, int i | - SsaImpl::lastRefBeforeRedef(def, bb, i, next) and - read = bb.getNode(i) and - read.getElement() instanceof AssignableRead + SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and + read.asExprAtNode(bb.getNode(i)) instanceof AssignableRead ) } - private Ssa::Definition getSsaDefinition(Node n) { - result = n.(SsaDefinitionNode).getDefinition() + private SsaImpl::DefinitionExt getSsaDefinitionExt(Node n) { + result = n.(SsaDefinitionExtNode).getDefinitionExt() or result = n.(ExplicitParameterNode).getSsaDefinition() } @@ -344,9 +355,9 @@ module LocalFlow { * Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo` * involving SSA definition `def`. */ - predicate localSsaFlowStepUseUse(Ssa::Definition def, Node nodeFrom, Node nodeTo) { + predicate localSsaFlowStepUseUse(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo | - SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and + SsaImpl::adjacentReadPairSameVarExt(def, cfnFrom, cfnTo) and nodeTo = TExprNode(cfnTo) and nodeFrom = TExprNode(cfnFrom) ) @@ -356,31 +367,22 @@ module LocalFlow { * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving * SSA definition `def`. */ - predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) { + predicate localSsaFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { // Flow from SSA definition/parameter to first read - exists(ControlFlow::Node cfn | - def = getSsaDefinition(nodeFrom) and - nodeTo.asExprAtNode(cfn) = def.getAFirstReadAtNode(cfn) - ) + def = getSsaDefinitionExt(nodeFrom) and + SsaImpl::firstReadSameVarExt(def, nodeTo.(ExprNode).getControlFlowNode()) or // Flow from read to next read localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo) or - // Flow into phi/uncertain SSA definition node from def - exists(Ssa::Definition next | - localFlowSsaInputFromDef(nodeFrom, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() - | - def = next.(Ssa::PhiNode).getAnInput() - or - def = next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ) + // Flow into phi (read)/uncertain SSA definition node from def + localFlowSsaInputFromDef(nodeFrom, def, nodeTo) } /** * Holds if the source variable of SSA definition `def` is an instance field. */ - predicate usesInstanceField(Ssa::Definition def) { + predicate usesInstanceField(SsaImpl::DefinitionExt def) { exists(Ssa::SourceVariables::FieldOrPropSourceVariable fp | fp = def.getSourceVariable() | not fp.getAssignable().(Modifiable).isStatic() ) @@ -389,25 +391,23 @@ module LocalFlow { predicate localFlowCapturedVarStep(Node nodeFrom, ImplicitCapturedArgumentNode nodeTo) { // Flow from SSA definition to implicit captured variable argument exists(Ssa::ExplicitDefinition def, ControlFlow::Nodes::ElementNode call | - def = getSsaDefinition(nodeFrom) and + def = getSsaDefinitionExt(nodeFrom) and def.isCapturedVariableDefinitionFlowIn(_, call, _) and nodeTo = TImplicitCapturedArgumentNode(call, def.getSourceVariable().getAssignable()) ) } private module CilFlow { - private import semmle.code.cil.internal.SsaImpl as CilSsaImpl - /** * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which * can reach `next`. */ private predicate localFlowCilSsaInput( - Node nodeFrom, CilSsa::Definition def, CilSsa::Definition next + Node nodeFrom, CilSsaImpl::DefinitionExt def, CilSsaImpl::DefinitionExt next ) { - exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedef(def, bb, i, next) | - def.definesAt(_, bb, i) and - def = nodeFrom.(CilSsaDefinitionNode).getDefinition() + exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedefExt(def, bb, i, next) | + def.definesAt(_, bb, i, _) and + def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() or nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess)) ) @@ -417,30 +417,33 @@ module LocalFlow { * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving * CIL SSA definition `def`. */ - private predicate localCilSsaFlowStep(CilSsa::Definition def, Node nodeFrom, Node nodeTo) { + private predicate localCilSsaFlowStep(CilSsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) { // Flow into SSA definition exists(CIL::VariableUpdate vu | - vu = def.getVariableUpdate() and + vu = def.(CilSsa::Definition).getVariableUpdate() and vu.getSource() = asCilDataFlowNode(nodeFrom) and - def = nodeTo.(CilSsaDefinitionNode).getDefinition() + def = nodeTo.(CilSsaDefinitionExtNode).getDefinition() ) or // Flow from SSA definition to first read - def = nodeFrom.(CilSsaDefinitionNode).getDefinition() and - nodeTo = TCilExprNode(CilSsaImpl::getAFirstRead(def)) + def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and + nodeTo = TCilExprNode(CilSsaImpl::getAFirstReadExt(def)) or // Flow from read to next read exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo | - CilSsaImpl::hasAdjacentReads(def, readFrom, readTo) and + CilSsaImpl::hasAdjacentReadsExt(def, readFrom, readTo) and nodeTo = TCilExprNode(readTo) and nodeFrom = TCilExprNode(readFrom) ) or - // Flow into phi node - exists(CilSsa::PhiNode phi | + // Flow into phi (read) node + exists(CilSsaImpl::DefinitionExt phi | localFlowCilSsaInput(nodeFrom, def, phi) and - phi = nodeTo.(CilSsaDefinitionNode).getDefinition() and - def = CilSsaImpl::getAPhiInput(phi) + phi = nodeTo.(CilSsaDefinitionExtNode).getDefinition() + | + phi instanceof CilSsa::PhiNode + or + phi instanceof CilSsaImpl::PhiReadNode ) } @@ -466,7 +469,7 @@ module LocalFlow { } predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) { - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | localSsaFlowStep(def, nodeFrom, nodeTo) and not usesInstanceField(def) ) @@ -528,26 +531,20 @@ module LocalFlow { predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) or - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and not LocalFlow::usesInstanceField(def) ) or - // Flow into phi/uncertain SSA definition node from read - exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next | - LocalFlow::localFlowSsaInputFromExpr(read, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() and - def = - [ - next.(Ssa::PhiNode).getAnInput(), - next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ] + // Flow into phi (read)/uncertain SSA definition node from read + exists(SsaImpl::DefinitionExt def, Node read | + LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) | - exists(nodeFrom.asExprAtNode(read)) and + nodeFrom = read and not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) or - exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read)) + nodeFrom.(PostUpdateNode).getPreUpdateNode() = read ) or LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo) @@ -813,8 +810,8 @@ private module Cached { cfn.getElement() instanceof Expr } or TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or - TCilSsaDefinitionNode(CilSsa::Definition def) or - TSsaDefinitionNode(Ssa::Definition def) { + TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or + TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) { // Handled by `TExplicitParameterNode` below not def.(Ssa::ExplicitDefinition).getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition @@ -880,24 +877,18 @@ private module Cached { or LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo) or - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and LocalFlow::usesInstanceField(def) ) or - // Flow into phi/uncertain SSA definition node from read - exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next | - LocalFlow::localFlowSsaInputFromExpr(read, def, next) and - next = nodeTo.(SsaDefinitionNode).getDefinition() and - def = - [ - next.(Ssa::PhiNode).getAnInput(), - next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition() - ] + // Flow into phi (read)/uncertain SSA definition node from read + exists(SsaImpl::DefinitionExt def, Node read | + LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) | - exists(nodeFrom.asExprAtNode(read)) + nodeFrom = read or - exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read)) + nodeFrom.(PostUpdateNode).getPreUpdateNode() = read ) or // Simple flow through library code is included in the exposed local @@ -913,6 +904,13 @@ private module Cached { TElementContent() or TSyntheticFieldContent(SyntheticField f) + cached + newtype TContentApprox = + TFieldApproxContent(string firstChar) { firstChar = approximateFieldContent(_) } or + TPropertyApproxContent(string firstChar) { firstChar = approximatePropertyContent(_) } or + TElementApproxContent() or + TSyntheticFieldApproxContent() + pragma[nomagic] private predicate commonSubTypeGeneral(DataFlowTypeOrUnifiable t1, RelevantDataFlowType t2) { not t1 instanceof Gvn::TypeParameterGvnType and @@ -945,9 +943,11 @@ import Cached /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { - exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() | + exists(SsaImpl::DefinitionExt def | def = n.(SsaDefinitionExtNode).getDefinitionExt() | def instanceof Ssa::PhiNode or + def instanceof SsaImpl::PhiReadNode + or def instanceof Ssa::ImplicitEntryDefinition or def instanceof Ssa::ImplicitCallDefinition @@ -978,13 +978,13 @@ predicate nodeIsHidden(Node n) { } /** A CIL SSA definition, viewed as a node in a data flow graph. */ -class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode { - CilSsa::Definition def; +class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode { + CilSsaImpl::DefinitionExt def; - CilSsaDefinitionNode() { this = TCilSsaDefinitionNode(def) } + CilSsaDefinitionExtNode() { this = TCilSsaDefinitionExtNode(def) } /** Gets the underlying SSA definition. */ - CilSsa::Definition getDefinition() { result = def } + CilSsaImpl::DefinitionExt getDefinition() { result = def } override DataFlowCallable getEnclosingCallableImpl() { result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod() @@ -1000,13 +1000,13 @@ class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode { } /** An SSA definition, viewed as a node in a data flow graph. */ -class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { - Ssa::Definition def; +class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode { + SsaImpl::DefinitionExt def; - SsaDefinitionNode() { this = TSsaDefinitionNode(def) } + SsaDefinitionExtNode() { this = TSsaDefinitionExtNode(def) } /** Gets the underlying SSA definition. */ - Ssa::Definition getDefinition() { result = def } + SsaImpl::DefinitionExt getDefinitionExt() { result = def } override DataFlowCallable getEnclosingCallableImpl() { result.asCallable() = def.getEnclosingCallable() @@ -1014,7 +1014,9 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { override Type getTypeImpl() { result = def.getSourceVariable().getType() } - override ControlFlow::Node getControlFlowNodeImpl() { result = def.getControlFlowNode() } + override ControlFlow::Node getControlFlowNodeImpl() { + result = def.(Ssa::Definition).getControlFlowNode() + } override Location getLocationImpl() { result = def.getLocation() } @@ -1108,13 +1110,11 @@ private module ParameterNodes { * } } * ``` */ - class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionNode { - override SsaCapturedEntryDefinition def; - - ImplicitCapturedParameterNode() { def = this.getDefinition() } + class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionExtNode { + ImplicitCapturedParameterNode() { def instanceof SsaCapturedEntryDefinition } /** Gets the captured variable that this implicit parameter models. */ - LocalScopeVariable getVariable() { result = def.getVariable() } + LocalScopeVariable getVariable() { result = def.(SsaCapturedEntryDefinition).getVariable() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { pos.isImplicitCapturedParameterPosition(def.getSourceVariable().getAssignable()) and @@ -1349,12 +1349,12 @@ private module ReturnNodes { * A data-flow node that represents an assignment to an `out` or a `ref` * parameter. */ - class OutRefReturnNode extends ReturnNode, SsaDefinitionNode { + class OutRefReturnNode extends ReturnNode, SsaDefinitionExtNode { OutRefReturnKind kind; OutRefReturnNode() { exists(Parameter p | - this.getDefinition().isLiveOutRefParameterDefinition(p) and + this.getDefinitionExt().(Ssa::Definition).isLiveOutRefParameterDefinition(p) and kind.getPosition() = p.getPosition() | p.isOut() and kind instanceof OutReturnKind @@ -1438,11 +1438,11 @@ private module ReturnNodes { * } } * ``` */ - class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionNode { + class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionExtNode { private Ssa::ExplicitDefinition edef; ImplicitCapturedReturnNode() { - edef = this.getDefinition() and + edef = this.getDefinitionExt() and edef.isCapturedVariableDefinitionFlowOut(_, _) } @@ -1450,8 +1450,8 @@ private module ReturnNodes { * Holds if the value at this node may flow out to the implicit call definition * at `node`, using one or more calls. */ - predicate flowsOutTo(SsaDefinitionNode node, boolean additionalCalls) { - edef.isCapturedVariableDefinitionFlowOut(node.getDefinition(), additionalCalls) + predicate flowsOutTo(SsaDefinitionExtNode node, boolean additionalCalls) { + edef.isCapturedVariableDefinitionFlowOut(node.getDefinitionExt(), additionalCalls) } override ImplicitCapturedReturnKind getKind() { @@ -1558,13 +1558,13 @@ private module OutNodes { * A data-flow node that reads a value returned implicitly by a callable * using a captured variable. */ - class CapturedOutNode extends OutNode, SsaDefinitionNode { + class CapturedOutNode extends OutNode, SsaDefinitionExtNode { private DataFlowCall call; CapturedOutNode() { exists(ImplicitCapturedReturnNode n, boolean additionalCalls, ControlFlow::Node cfn | n.flowsOutTo(this, additionalCalls) and - cfn = this.getDefinition().getControlFlowNode() + cfn = this.getDefinitionExt().(Ssa::Definition).getControlFlowNode() | additionalCalls = false and call = csharpCall(_, cfn) or @@ -1576,7 +1576,7 @@ private module OutNodes { override DataFlowCall getCall(ReturnKind kind) { result = call and kind.(ImplicitCapturedReturnKind).getVariable() = - this.getDefinition().getSourceVariable().getAssignable() + this.getDefinitionExt().getSourceVariable().getAssignable() } } @@ -1857,7 +1857,7 @@ predicate readStep(Node node1, Content c, Node node2) { exists(ForeachStmt fs, Ssa::ExplicitDefinition def | x.hasDefPath(fs.getIterableExpr(), node1.getControlFlowNode(), def.getADefinition(), def.getControlFlowNode()) and - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and c instanceof ElementContent ) or @@ -1880,7 +1880,7 @@ predicate readStep(Node node1, Content c, Node node2) { or // item = variable in node1 = (..., variable, ...) exists(AssignableDefinitions::TupleAssignmentDefinition tad, Ssa::ExplicitDefinition def | - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and def.getADefinition() = tad and tad.getLeaf() = item and hasNodePath(x, node1, node2) @@ -1889,7 +1889,7 @@ predicate readStep(Node node1, Content c, Node node2) { // item = variable in node1 = (..., variable, ...) in a case/is var (..., ...) te = any(PatternExpr pe).getAChildExpr*() and exists(AssignableDefinitions::LocalVariableDefinition lvd, Ssa::ExplicitDefinition def | - node2.(SsaDefinitionNode).getDefinition() = def and + node2.(SsaDefinitionExtNode).getDefinitionExt() = def and def.getADefinition() = lvd and lvd.getDeclaration() = item and hasNodePath(x, node1, node2) @@ -2223,7 +2223,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { /** Extra data-flow steps needed for lambda flow analysis. */ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { - exists(Ssa::Definition def | + exists(SsaImpl::DefinitionExt def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and LocalFlow::usesInstanceField(def) and preservesValue = true @@ -2253,6 +2253,46 @@ predicate allowParameterReturnInSelf(ParameterNode p) { FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) } +/** An approximated `Content`. */ +class ContentApprox extends TContentApprox { + /** Gets a textual representation of this approximated `Content`. */ + string toString() { + exists(string firstChar | + this = TFieldApproxContent(firstChar) and result = "approximated field " + firstChar + ) + or + exists(string firstChar | + this = TPropertyApproxContent(firstChar) and result = "approximated property " + firstChar + ) + or + this = TElementApproxContent() and result = "element" + or + this = TSyntheticFieldApproxContent() and result = "approximated synthetic field" + } +} + +/** Gets a string for approximating the name of a field. */ +private string approximateFieldContent(FieldContent fc) { + result = fc.getField().getName().prefix(1) +} + +/** Gets a string for approximating the name of a property. */ +private string approximatePropertyContent(PropertyContent pc) { + result = pc.getProperty().getName().prefix(1) +} + +/** Gets an approximated value for content `c`. */ +pragma[nomagic] +ContentApprox getContentApprox(Content c) { + result = TFieldApproxContent(approximateFieldContent(c)) + or + result = TPropertyApproxContent(approximatePropertyContent(c)) + or + c instanceof ElementContent and result = TElementApproxContent() + or + c instanceof SyntheticFieldContent and result = TSyntheticFieldApproxContent() +} + /** * A module importing the modules that provide synthetic field declarations, * ensuring that they are visible to the taint tracking / data flow library. @@ -2328,8 +2368,8 @@ module Csv { ) } - /** Computes the first 4 columns for negative CSV rows of `c`. */ - string asPartialNegativeModel(DotNet::Callable c) { + /** Computes the first 4 columns for neutral CSV rows of `c`. */ + string asPartialNeutralModel(DotNet::Callable c) { exists(string namespace, string type, string name, string parameters | partialModel(c, namespace, type, name, parameters) and result = diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index f6520147e19..b22712087f2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -119,10 +119,10 @@ class ParameterNode extends Node instanceof ParameterNodeImpl { } /** A definition, viewed as a node in a data flow graph. */ -class AssignableDefinitionNode extends Node, TSsaDefinitionNode { +class AssignableDefinitionNode extends Node, TSsaDefinitionExtNode { private Ssa::ExplicitDefinition edef; - AssignableDefinitionNode() { this = TSsaDefinitionNode(edef) } + AssignableDefinitionNode() { this = TSsaDefinitionExtNode(edef) } /** Gets the underlying definition. */ AssignableDefinition getDefinition() { result = this.getDefinitionAtNode(_) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 4d41254e5e9..b61142c33a7 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -241,19 +241,25 @@ module Public { } /** - * Holds if the summary is auto generated. + * Holds if the summary is auto generated and not manually generated. */ predicate isAutoGenerated() { none() } - } - - /** A callable with a flow summary stating there is no flow via the callable. */ - class NegativeSummarizedCallable extends SummarizedCallableBase { - NegativeSummarizedCallable() { negativeSummaryElement(this, _) } /** - * Holds if the negative summary is auto generated. + * Holds if the summary has the given provenance where `true` is + * `generated` and `false` is `manual`. */ - predicate isAutoGenerated() { negativeSummaryElement(this, true) } + predicate hasProvenance(boolean generated) { none() } + } + + /** A callable where there is no flow via the callable. */ + class NeutralCallable extends SummarizedCallableBase { + NeutralCallable() { neutralElement(this, _) } + + /** + * Holds if the neutral is auto generated. + */ + predicate isAutoGenerated() { neutralElement(this, true) } } } @@ -520,7 +526,8 @@ module Private { predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or - isParameterPostUpdate(_, c, pos) + // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context + any(SummaryNodeState state).isOutputState(c, SummaryComponentStack::argument(pos)) } private predicate callbackOutput( @@ -1011,6 +1018,10 @@ module Private { } override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) } + + override predicate hasProvenance(boolean generated) { + summaryElement(this, _, _, _, generated) + } } /** Holds if component `c` of specification `spec` cannot be parsed. */ @@ -1160,9 +1171,9 @@ module Private { string toString() { result = super.toString() } } - /** A flow summary to include in the `negativeSummary/1` query predicate. */ - abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable { - /** Gets the string representation of this callable used by `summary/1`. */ + /** A model to include in the `neutral/1` query predicate. */ + abstract class RelevantNeutralCallable instanceof NeutralCallable { + /** Gets the string representation of this callable used by `neutral/1`. */ abstract string getCallableCsv(); string toString() { result = super.toString() } @@ -1179,13 +1190,13 @@ module Private { if c.isAutoGenerated() then result = "generated" else result = "manual" } - private string renderProvenanceNegative(NegativeSummarizedCallable c) { + private string renderProvenanceNeutral(NeutralCallable c) { if c.isAutoGenerated() then result = "generated" else result = "manual" } /** * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. - * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance"", + * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance", * ext is hardcoded to empty. */ query predicate summary(string csv) { @@ -1204,14 +1215,14 @@ module Private { } /** - * Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes. + * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes. * The syntax is: "namespace;type;name;signature;provenance"", */ - query predicate negativeSummary(string csv) { - exists(RelevantNegativeSummarizedCallable c | + query predicate neutral(string csv) { + exists(RelevantNeutralCallable c | csv = c.getCallableCsv() // Callable information - + renderProvenanceNegative(c) // provenance + + renderProvenanceNeutral(c) // provenance ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 93cd70f63c2..44baca91929 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -121,12 +121,12 @@ predicate summaryElement(Callable c, string input, string output, string kind, b } /** - * Holds if a negative flow summary exists for `c`, which means that there is no - * flow through `c`. The flag `generated` states whether the summary is autogenerated. + * Holds if a neutral model exists for `c`, which means that there is no + * flow through `c`. The flag `generated` states whether the neutral model is autogenerated. */ -predicate negativeSummaryElement(Callable c, boolean generated) { +predicate neutralElement(Callable c, boolean generated) { exists(string namespace, string type, string name, string signature, string provenance | - negativeSummaryModel(namespace, type, name, signature, provenance) and + neutralModel(namespace, type, name, signature, provenance) and generated = isGenerated(provenance) and c = interpretElement(namespace, type, false, name, signature, "") ) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index adfacd2970a..80d3dbd28ab 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -49,7 +49,23 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -import SsaImplCommon::Make +private import SsaImplCommon::Make as Impl + +class Definition = Impl::Definition; + +class WriteDefinition = Impl::WriteDefinition; + +class UncertainWriteDefinition = Impl::UncertainWriteDefinition; + +class PhiNode = Impl::PhiNode; + +module Consistency = Impl::Consistency; + +module ExposedForTestingOnly { + predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4; + + predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3; +} /** * Holds if the `i`th node of basic block `bb` reads source variable `v`. @@ -1072,23 +1088,43 @@ private predicate adjacentDefRead( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2, SsaInput::SourceVariable v ) { - adjacentDefRead(def, bb1, i1, bb2, i2) and + Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and v = def.getSourceVariable() } private predicate adjacentDefReachesRead( - Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 + Definition def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1, + SsaInput::BasicBlock bb2, int i2 ) { - exists(SsaInput::SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) | + adjacentDefRead(def, bb1, i1, bb2, i2, v) and + ( def.definesAt(v, bb1, i1) or SsaInput::variableRead(bb1, i1, v, true) ) or exists(SsaInput::BasicBlock bb3, int i3 | - adjacentDefReachesRead(def, bb1, i1, bb3, i3) and + adjacentDefReachesRead(def, v, bb1, i1, bb3, i3) and SsaInput::variableRead(bb3, i3, _, false) and - adjacentDefRead(def, bb3, i3, bb2, i2) + Impl::adjacentDefRead(def, bb3, i3, bb2, i2) + ) +} + +private predicate adjacentDefReachesReadExt( + DefinitionExt def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1, + SsaInput::BasicBlock bb2, int i2 +) { + Impl::adjacentDefReadExt(def, v, bb1, i1, bb2, i2) and + ( + def.definesAt(v, bb1, i1, _) + or + SsaInput::variableRead(bb1, i1, v, true) + ) + or + exists(SsaInput::BasicBlock bb3, int i3 | + adjacentDefReachesReadExt(def, v, bb1, i1, bb3, i3) and + SsaInput::variableRead(bb3, i3, v, false) and + Impl::adjacentDefReadExt(def, v, bb3, i3, bb2, i2) ) } @@ -1097,25 +1133,49 @@ pragma[nomagic] private predicate adjacentDefSkipUncertainReads( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 ) { - adjacentDefReachesRead(def, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, _, true) + exists(SsaInput::SourceVariable v | + adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, true) + ) +} + +/** Same as `adjacentDefReadExt`, but skips uncertain reads. */ +pragma[nomagic] +private predicate adjacentDefSkipUncertainReadsExt( + DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 +) { + exists(SsaInput::SourceVariable v | + adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, true) + ) } private predicate adjacentDefReachesUncertainRead( Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 ) { - adjacentDefReachesRead(def, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, _, false) + exists(SsaInput::SourceVariable v | + adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, false) + ) +} + +private predicate adjacentDefReachesUncertainReadExt( + DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 +) { + exists(SsaInput::SourceVariable v | + adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and + SsaInput::variableRead(bb2, i2, v, false) + ) } /** Same as `lastRefRedef`, but skips uncertain reads. */ pragma[nomagic] private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) { - lastRef(def, bb, i) and + Impl::lastRef(def, bb, i) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRef(def, bb0, i0) and + Impl::lastRef(def, bb0, i0) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } @@ -1237,7 +1297,7 @@ private module Cached { v = def.getSourceVariable() and capturedReadIn(_, _, v, edef.getSourceVariable(), c, additionalCalls) and def = def0.getAnUltimateDefinition() and - ssaDefReachesRead(_, def0, bb, i) and + Impl::ssaDefReachesRead(_, def0, bb, i) and capturedReadIn(bb, i, v, _, _, _) and c = bb.getNode(i) ) @@ -1264,18 +1324,18 @@ private module Cached { cached predicate isLiveAtEndOfBlock(Definition def, ControlFlow::BasicBlock bb) { - ssaDefReachesEndOfBlock(bb, def, _) + Impl::ssaDefReachesEndOfBlock(bb, def, _) } cached - Definition phiHasInputFromBlock(PhiNode phi, ControlFlow::BasicBlock bb) { - phiHasInputFromBlock(phi, result, bb) + Definition phiHasInputFromBlock(Ssa::PhiNode phi, ControlFlow::BasicBlock bb) { + Impl::phiHasInputFromBlock(phi, result, bb) } cached AssignableRead getAReadAtNode(Definition def, ControlFlow::Node cfn) { exists(Ssa::SourceVariable v, ControlFlow::BasicBlock bb, int i | - ssaDefReachesRead(v, def, bb, i) and + Impl::ssaDefReachesRead(v, def, bb, i) and variableReadActual(bb, i, v) and cfn = bb.getNode(i) and result.getAControlFlowNode() = cfn @@ -1295,6 +1355,19 @@ private module Cached { ) } + /** + * Holds if the value defined at SSA definition `def` can reach a read at `cfn`, + * without passing through any other read. + */ + cached + predicate firstReadSameVarExt(DefinitionExt def, ControlFlow::Node cfn) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1, _) and + adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and + cfn = bb2.getNode(i2) + ) + } + /** * Holds if the read at `cfn2` is a read of the same SSA definition `def` * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without @@ -1310,18 +1383,49 @@ private module Cached { ) } - /** Same as `lastRefRedef`, but skips uncertain reads. */ + /** + * Holds if the read at `cfn2` is a read of the same SSA definition `def` + * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without + * passing through another read. + */ + cached + predicate adjacentReadPairSameVarExt( + DefinitionExt def, ControlFlow::Node cfn1, ControlFlow::Node cfn2 + ) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + cfn1 = bb1.getNode(i1) and + variableReadActual(bb1, i1, _) and + adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and + cfn2 = bb2.getNode(i2) + ) + } + cached predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) { - lastRefRedef(def, bb, i, next) and + Impl::lastRefRedef(def, bb, i, next) and not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) or exists(SsaInput::BasicBlock bb0, int i0 | - lastRefRedef(def, bb0, i0, next) and + Impl::lastRefRedef(def, bb0, i0, next) and adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) ) } + cached + predicate lastRefBeforeRedefExt( + DefinitionExt def, ControlFlow::BasicBlock bb, int i, DefinitionExt next + ) { + exists(SsaInput::SourceVariable v | + Impl::lastRefRedefExt(def, v, bb, i, next) and + not SsaInput::variableRead(bb, i, v, false) + ) + or + exists(SsaInput::BasicBlock bb0, int i0 | + Impl::lastRefRedefExt(def, _, bb0, i0, next) and + adjacentDefReachesUncertainReadExt(def, bb, i, bb0, i0) + ) + } + cached predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) { exists(ControlFlow::BasicBlock bb, int i | @@ -1333,7 +1437,7 @@ private module Cached { cached Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) { - uncertainWriteDefinitionInput(def, result) + Impl::uncertainWriteDefinitionInput(def, result) } cached @@ -1343,10 +1447,64 @@ private module Cached { v = def.getSourceVariable() and p = v.getAssignable() and def = def0.getAnUltimateDefinition() and - ssaDefReachesRead(_, def0, bb, i) and + Impl::ssaDefReachesRead(_, def0, bb, i) and outRefExitRead(bb, i, v) ) } } import Cached + +private string getSplitString(DefinitionExt def) { + exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn | + def.definesAt(_, bb, i, _) and + result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString() + | + cfn = bb.getNode(i) + or + not exists(bb.getNode(i)) and + cfn = bb.getFirstNode() + ) +} + +string getToStringPrefix(DefinitionExt def) { + result = "[" + getSplitString(def) + "] " + or + not exists(getSplitString(def)) and + result = "" +} + +/** + * An extended static single assignment (SSA) definition. + * + * This is either a normal SSA definition (`Definition`) or a + * phi-read node (`PhiReadNode`). + * + * Only intended for internal use. + */ +class DefinitionExt extends Impl::DefinitionExt { + override string toString() { result = this.(Ssa::Definition).toString() } + + /** Gets the location of this definition. */ + Location getLocation() { result = this.(Ssa::Definition).getLocation() } + + /** Gets the enclosing callable of this definition. */ + Callable getEnclosingCallable() { result = this.(Ssa::Definition).getEnclosingCallable() } +} + +/** + * A phi-read node. + * + * Only intended for internal use. + */ +class PhiReadNode extends DefinitionExt, Impl::PhiReadNode { + override string toString() { + result = getToStringPrefix(this) + "SSA phi read(" + this.getSourceVariable() + ")" + } + + override Location getLocation() { result = this.getBasicBlock().getLocation() } + + override Callable getEnclosingCallable() { + result = this.getSourceVariable().getEnclosingCallable() + } +} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ConstantUtils.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ConstantUtils.qll index c067e29d320..e3f5deb9898 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ConstantUtils.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ConstantUtils.qll @@ -13,7 +13,7 @@ private class ExprNode = ControlFlow::Nodes::ExprNode; * Holds if `pa` is an access to the `Length` property of an array. */ predicate systemArrayLengthAccess(PropertyAccess pa) { - propertyOverrides(pa.getTarget(), "System.Array", "Length") + propertyOverrides(pa.getTarget(), "System", "Array", "Length") } /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll index 067a9b94f45..ce7637ccd92 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll @@ -150,9 +150,9 @@ private module Impl { /** * Holds if property `p` matches `property` in `baseClass` or any overrides. */ - predicate propertyOverrides(Property p, string baseClass, string property) { + predicate propertyOverrides(Property p, string namespace, string baseClass, string property) { exists(Property p2 | - p2.getUnboundDeclaration().getDeclaringType().hasQualifiedName(baseClass) and + p2.getUnboundDeclaration().getDeclaringType().hasQualifiedName(namespace, baseClass) and p2.hasName(property) | p.overridesOrImplementsOrEquals(p2) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll index 04d0816a683..9102bf29131 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll @@ -83,10 +83,10 @@ private module Impl { */ predicate containerSizeAccess(ExprNode e) { exists(Property p | p = e.getExpr().(PropertyAccess).getTarget() | - propertyOverrides(p, "System.Collections.Generic.IEnumerable<>", "Count") or - propertyOverrides(p, "System.Collections.ICollection", "Count") or - propertyOverrides(p, "System.String", "Length") or - propertyOverrides(p, "System.Array", "Length") + propertyOverrides(p, "System.Collections.Generic", "IEnumerable<>", "Count") or + propertyOverrides(p, "System.Collections", "ICollection", "Count") or + propertyOverrides(p, "System", "String", "Length") or + propertyOverrides(p, "System", "Array", "Length") ) or e.getExpr() instanceof CountCall diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll index 03a24b37345..4251a7ae8b6 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll @@ -321,6 +321,18 @@ private predicate hasChildPattern(ControlFlowElement pm, Expr child) { mid instanceof @tuple_expr and child = mid.getAChildExpr() ) + or + exists(Expr mid | + hasChildPattern(pm, mid) and + mid instanceof @list_pattern_expr and + child = mid.getAChildExpr() + ) + or + exists(Expr mid | + hasChildPattern(pm, mid) and + mid instanceof @slice_pattern_expr and + child = mid.getAChildExpr() + ) } /** @@ -506,6 +518,26 @@ class PositionalPatternExpr extends PatternExpr, @positional_pattern_expr { override string getAPrimaryQlClass() { result = "PositionalPatternExpr" } } +/** A list pattern. For example `[1, 2, int y]` in `x is [1, 2, int y]`. */ +class ListPatternExpr extends PatternExpr, @list_pattern_expr { + override string toString() { result = "[ ... ]" } + + /** Gets the `n`th pattern. */ + PatternExpr getPattern(int n) { result = this.getChild(n) } + + override string getAPrimaryQlClass() { result = "ListPatternExpr" } +} + +/** A slice pattern. For example `..` in `x is [1, .., 2]. */ +class SlicePatternExpr extends PatternExpr, @slice_pattern_expr { + override string toString() { result = ".." } + + /** Gets the subpattern, if any. */ + PatternExpr getPattern() { result = this.getChild(0) } + + override string getAPrimaryQlClass() { result = "SlicePatternExpr" } +} + /** A unary pattern. For example, `not 1`. */ class UnaryPatternExpr extends PatternExpr, @unary_pattern_expr { /** Gets the underlying pattern. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Dapper.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Dapper.qll index 3d25f4389fd..dcfb5f2260f 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Dapper.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Dapper.qll @@ -9,7 +9,7 @@ private import semmle.code.csharp.frameworks.system.Data module Dapper { /** The namespace `Dapper`. */ class DapperNamespace extends Namespace { - DapperNamespace() { this.hasQualifiedName("Dapper") } + DapperNamespace() { this.getFullName() = "Dapper" } } /** A class in `Dapper`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 4c4b4e7bd1d..1bd86b98ff2 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -9,7 +9,6 @@ private import semmle.code.csharp.frameworks.system.data.Entity private import semmle.code.csharp.frameworks.system.collections.Generic private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.dataflow.FlowSummary -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate /** @@ -21,7 +20,7 @@ module DataAnnotations { class NotMappedAttribute extends Attribute { NotMappedAttribute() { this.getType() - .hasQualifiedName("System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute") + .hasQualifiedName("System.ComponentModel.DataAnnotations.Schema", "NotMappedAttribute") } } } @@ -38,11 +37,7 @@ private predicate isNotMapped(Attributable a) { module EntityFramework { /** An EF6 or EFCore namespace. */ class EFNamespace extends Namespace { - EFNamespace() { - this.getQualifiedName() = "Microsoft.EntityFrameworkCore" - or - this.getQualifiedName() = "System.Data.Entity" - } + EFNamespace() { this.getFullName() = ["Microsoft.EntityFrameworkCore", "System.Data.Entity"] } } /** A taint source where the data has come from a mapped property stored in the database. */ @@ -163,7 +158,7 @@ module EntityFramework { /** The struct `Microsoft.EntityFrameworkCore.RawSqlString`. */ private class RawSqlStringStruct extends Struct { - RawSqlStringStruct() { this.getQualifiedName() = "Microsoft.EntityFrameworkCore.RawSqlString" } + RawSqlStringStruct() { this.hasQualifiedName("Microsoft.EntityFrameworkCore", "RawSqlString") } /** Gets a conversion operator from `string` to `RawSqlString`. */ ConversionOperator getAConversionTo() { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index 373194ef366..7a7166baea1 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -27,15 +27,15 @@ class FormatMethod extends Method { or (this.hasName("Write") or this.hasName("WriteLine")) and ( - declType.hasQualifiedName("System.Console") + declType.hasQualifiedName("System", "Console") or - declType.hasQualifiedName("System.IO.TextWriter") + declType.hasQualifiedName("System.IO", "TextWriter") or - declType.hasQualifiedName("System.Diagnostics.Debug") and + declType.hasQualifiedName("System.Diagnostics", "Debug") and this.getParameter(1).getType() instanceof ArrayType ) or - declType.hasQualifiedName("System.Diagnostics.Trace") and + declType.hasQualifiedName("System.Diagnostics", "Trace") and ( this.hasName("TraceError") or this.hasName("TraceInformation") or @@ -43,14 +43,14 @@ class FormatMethod extends Method { ) or this.hasName("TraceInformation") and - declType.hasQualifiedName("System.Diagnostics.TraceSource") + declType.hasQualifiedName("System.Diagnostics", "TraceSource") or this.hasName("Print") and - declType.hasQualifiedName("System.Diagnostics.Debug") + declType.hasQualifiedName("System.Diagnostics", "Debug") ) or this.hasName("Assert") and - declType.hasQualifiedName("System.Diagnostics.Debug") and + declType.hasQualifiedName("System.Diagnostics", "Debug") and this.getNumberOfParameters() = 4 ) } @@ -65,7 +65,7 @@ class FormatMethod extends Method { else if this.hasName("Assert") and - this.getDeclaringType().hasQualifiedName("System.Diagnostics.Debug") + this.getDeclaringType().hasQualifiedName("System.Diagnostics", "Debug") then result = 2 else result = 0 } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll index 73a506bc555..69ae1ec292b 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll @@ -3,13 +3,12 @@ */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow /** Definitions relating to the `Json.NET` package. */ module JsonNET { /** The namespace `Newtonsoft.Json`. */ class JsonNETNamespace extends Namespace { - JsonNETNamespace() { this.hasQualifiedName("Newtonsoft.Json") } + JsonNETNamespace() { this.getFullName() = "Newtonsoft.Json" } } /** A class in `Newtonsoft.Json`. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll index e0705ac7d98..9ab9a026fd2 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll @@ -4,7 +4,7 @@ import csharp /** The `Moq.Language` Namespace. */ class MoqLanguageNamespace extends Namespace { - MoqLanguageNamespace() { this.hasQualifiedName("Moq.Language") } + MoqLanguageNamespace() { this.getFullName() = "Moq.Language" } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll index c416d6f6849..a0b90cb9146 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll @@ -14,7 +14,7 @@ module NHibernate { /** The interface `NHibernamte.ISession`. */ class ISessionInterface extends Interface { - ISessionInterface() { this.hasQualifiedName("NHibernate.ISession") } + ISessionInterface() { this.hasQualifiedName("NHibernate", "ISession") } /** Gets a parameter that uses a mapped object. */ Parameter getAMappedObjectParameter() { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll index ba3248fea95..27021573f38 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll @@ -6,7 +6,6 @@ */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow /** A class representing a Service */ private class ServiceClass extends Class { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index 258b7b3f794..f50f601b45f 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -7,7 +7,6 @@ private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.Dapper private import semmle.code.csharp.dataflow.DataFlow4 -private import semmle.code.csharp.dataflow.ExternalFlow /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { @@ -35,13 +34,14 @@ class IDbCommandConstructionSqlExpr extends SqlExpr, ObjectCreation { exists(InstanceConstructor ic | ic = this.getTarget() | ic.getDeclaringType().getABaseType*() instanceof SystemDataIDbCommandInterface and ic.getParameter(0).getType() instanceof StringType and - not ic.getDeclaringType() - .hasQualifiedName([ - // Known sealed classes: - "System.Data.SqlClient.SqlCommand", "System.Data.Odbc.OdbcCommand", - "System.Data.OleDb.OleDbCommand", "System.Data.EntityClient.EntityCommand", - "System.Data.SQLite.SQLiteCommand" - ]) + not exists(Type t | t = ic.getDeclaringType() | + // Known sealed classes: + t.hasQualifiedName("System.Data.SqlClient", "SqlCommand") or + t.hasQualifiedName("System.Data.Odbc", "OdbcCommand") or + t.hasQualifiedName("System.Data.OleDb", "OleDbCommand") or + t.hasQualifiedName("System.Data.EntityClient", "EntityCommand") or + t.hasQualifiedName("System.Data.SQLite", "SQLiteCommand") + ) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll index bf291f90879..c3e7d51f0ae 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll @@ -2,7 +2,6 @@ import csharp private import system.Reflection -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System` namespace. */ class SystemNamespace extends Namespace { @@ -258,9 +257,7 @@ class SystemNullReferenceExceptionClass extends SystemClass { } /** The `System.Object` class. */ -class SystemObjectClass extends SystemClass { - SystemObjectClass() { this instanceof ObjectType } - +class SystemObjectClass extends SystemClass instanceof ObjectType { /** Gets the `Equals(object)` method. */ Method getEqualsMethod() { result.getDeclaringType() = this and diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll index d9624b60dcc..f4cfb19a354 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll @@ -217,7 +217,7 @@ class MicrosoftAspNetCoreMvcController extends Class { .getType() .getABaseType*() // ApiControllerAttribute is derived from ControllerAttribute - .hasQualifiedName("Microsoft.AspNetCore.Mvc.ControllerAttribute") + .hasQualifiedName("Microsoft.AspNetCore.Mvc", "ControllerAttribute") ) and not this.getABaseType*().getAnAttribute() instanceof MicrosoftAspNetCoreMvcNonControllerAttribute @@ -288,7 +288,7 @@ class MicrosoftAspNetCoreHttpHttpResponse extends Class { /** An interface that is a wrapper around the collection of cookies in the response. */ class MicrosoftAspNetCoreHttpResponseCookies extends Interface { MicrosoftAspNetCoreHttpResponseCookies() { - this.hasQualifiedName("Microsoft.AspNetCore.Http.IResponseCookies") + this.hasQualifiedName("Microsoft.AspNetCore.Http", "IResponseCookies") } /** Gets the `Append` method. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/Owin.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/Owin.qll index 331e89b1bb8..9d9bf11f91c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/Owin.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/Owin.qll @@ -118,10 +118,10 @@ class MicrosoftOwinIOwinRequestClass extends Class { result.hasName("Scheme") } - /** Gets the `URI` property. */ + /** Gets the `Uri` property. */ Property getUriProperty() { result = this.getAProperty() and - result.hasName("URI") + result.hasName("Uri") } /** DEPRECATED: Alias for getUriProperty */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll index b7edb8e18dc..400e9954866 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/CodeDom.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.CodeDome` namespace. */ class SystemCodeDomNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll index 227fe34e3ca..1a35b7a807d 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Collections.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.FlowSummary /** The `System.Collections` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll index a95ae099295..f0e9fe29e96 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Data.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Data` namespace. */ class SystemDataNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll index 0b85d2ac24a..81a620c9e7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll @@ -2,7 +2,6 @@ import semmle.code.csharp.Type private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Diagnostics` namespace. */ class SystemDiagnosticsNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll index 5ceb73d4b64..9756bf9c982 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/IO.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.IO` namespace. */ class SystemIONamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll index 31b23334eaf..49076215471 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Linq.qll @@ -4,7 +4,6 @@ private import csharp as CSharp private import semmle.code.csharp.frameworks.System as System -private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Linq` namespace. */ module SystemLinq { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll index 1fbc46dbc9c..7c0aee741db 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Net.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Net` namespace. */ class SystemNetNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll index f8501eb82e9..02325e19383 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Security.qll @@ -1,7 +1,6 @@ /** Provides classes related to the namespace `System.Security`. */ import csharp -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.frameworks.System /** The `System.Security` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll index c81b28e29fe..fb4c37489af 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.FlowSummary /** The `System.Text` namespace. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll index 6680e22b796..8552c028c89 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Web.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.collections.Specialized -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Web` namespace. */ class SystemWebNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll index d6fd132ee6b..df6827660a0 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.dataflow.DataFlow3 -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Xml` namespace. */ class SystemXmlNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll index a7ab58da4f1..260fe6d0318 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Collections -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Collections.Generic` namespace. */ class SystemCollectionsGenericNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll index 4ffb7b5aa0c..2ddac761c4b 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Specialized.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Collections -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Collections.Specialized` namespace. */ class SystemCollectionsSpecializedNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll index 06a98d59f49..22c80fd4de6 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/Common.qll @@ -4,7 +4,6 @@ private import csharp as CSharp private import semmle.code.csharp.frameworks.system.Data as Data -private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow /** Definitions relating to the `System.Data.Common` namespace. */ module SystemDataCommon { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll index d5c58f13128..b1b777b0f69 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/io/Compression.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.IO -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.IO.Compression` namespace. */ class SystemIOCompressionNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll index 104ea2424dd..631a09058a3 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/net/Mail.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Net -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Net.Mail` namespace. */ class SystemNetMailNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll index e4426a81d14..9ae5ec90b24 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/runtime/CompilerServices.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Runtime private import semmle.code.csharp.dataflow.internal.DataFlowPrivate -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Runtime.CompilerServices` namespace. */ class SystemRuntimeCompilerServicesNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll index f922fb00669..40c07eef121 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/Cryptography.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Security -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Security.Cryptography` namespace. */ class SystemSecurityCryptographyNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/SymmetricAlgorithm.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/SymmetricAlgorithm.qll index d0b9c2e5239..85d8f5c4200 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/SymmetricAlgorithm.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/SymmetricAlgorithm.qll @@ -5,32 +5,33 @@ import csharp /** - * Holds if the object creation `oc` is the creation of the reference type with the specified `qualifiedName`, or a class derived from - * the class with the specified `qualifiedName`. + * Holds if the object creation `oc` is the creation of the reference type with the specified `qualifier` and `type`, or a class derived from + * the class with the specified `qualifier` and `type`. */ -private predicate isCreatingObject(ObjectCreation oc, string qualifiedName) { - exists(RefType t | t = oc.getType() | t.getBaseClass*().hasQualifiedName(qualifiedName)) +private predicate isCreatingObject(ObjectCreation oc, string qualifier, string type) { + exists(RefType t | t = oc.getType() | t.getBaseClass*().hasQualifiedName(qualifier, type)) } /** - * Holds if the method call `mc` is returning the reference type with the specified `qualifiedName`. + * Holds if the method call `mc` is returning the reference type with the specified `qualifier` and `type`. * and the target of the method call is a library method. */ -private predicate isReturningObject(MethodCall mc, string qualifiedName) { +private predicate isReturningObject(MethodCall mc, string qualifier, string type) { mc.getTarget().fromLibrary() and - exists(RefType t | t = mc.getType() | t.hasQualifiedName(qualifiedName)) + exists(RefType t | t = mc.getType() | t.hasQualifiedName(qualifier, type)) } /** - * Holds if the method call `mc` is a call on the library method target with the specified `qualifiedName` and `methodName`, and an argument at + * Holds if the method call `mc` is a call on the library method target with the specified `namespace`, `type` and `methodName`, and an argument at * index `argumentIndex` has the specified value `argumentValue` (case-insensitive). */ bindingset[argumentValue] private predicate isMethodCalledWithArg( - MethodCall mc, string qualifiedName, string methodName, int argumentIndex, string argumentValue + MethodCall mc, string namespace, string type, string methodName, int argumentIndex, + string argumentValue ) { mc.getTarget().fromLibrary() and - mc.getTarget().hasQualifiedName(qualifiedName, methodName) and + mc.getTarget().hasQualifiedName(namespace, type, methodName) and mc.getArgument(argumentIndex).getValue().toUpperCase() = argumentValue.toUpperCase() } @@ -60,13 +61,14 @@ class SymmetricAlgorithm extends Class { * Note: not all of the class names are supported on all platforms. */ predicate isCreatingDES(Expr e) { - isCreatingObject(e, "System.Security.Cryptography.DES") or - isReturningObject(e, "System.Security.Cryptography.DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, "DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isCreatingObject(e, "System.Security.Cryptography", "DES") or + isReturningObject(e, "System.Security.Cryptography", "DES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "DES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, "DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, + "DES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.DES") } @@ -75,21 +77,22 @@ predicate isCreatingDES(Expr e) { * Note: not all of the class names are supported on all platforms. */ predicate isCreatingTripleDES(Expr e) { - isCreatingObject(e, "System.Security.Cryptography.TripleDES") or - isReturningObject(e, "System.Security.Cryptography.TripleDES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isCreatingObject(e, "System.Security.Cryptography", "TripleDES") or + isReturningObject(e, "System.Security.Cryptography", "TripleDES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "TripleDES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, "3DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "3DES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "Triple DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.TripleDES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "TripleDES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, "3DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, + "3DES") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "Triple DES") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.TripleDES") } @@ -98,13 +101,14 @@ predicate isCreatingTripleDES(Expr e) { * Note: not all of the class names are supported on all platforms. */ predicate isCreatingRC2(Expr e) { - isCreatingObject(e, "System.Security.Cryptography.RC2") or - isReturningObject(e, "System.Security.Cryptography.RC2") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, "RC2") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isCreatingObject(e, "System.Security.Cryptography", "RC2") or + isReturningObject(e, "System.Security.Cryptography", "RC2") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "RC2") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.RC2") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, "RC2") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, + "RC2") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.RC2") } @@ -112,26 +116,26 @@ predicate isCreatingRC2(Expr e) { * Holds if the expression 'e' creates Rijndael symmetric algorithm. */ predicate isCreatingRijndael(Expr e) { - isCreatingObject(e, "System.Security.Cryptography.Rijndael") or - isReturningObject(e, "System.Security.Cryptography.Rijndael") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isCreatingObject(e, "System.Security.Cryptography", "Rijndael") or + isReturningObject(e, "System.Security.Cryptography", "Rijndael") or + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "Rijndael") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "RijndaelManaged") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.Rijndael") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.RijndaelManaged") or - isMethodCalledWithArg(e, "System.Security.Cryptography.SymmetricAlgorithm", "Create", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "SymmetricAlgorithm", "Create", 0, "System.Security.Cryptography.SymmetricAlgorithm") or // this creates Rijndael - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "Rijndael") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.Rijndael") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "RijndaelManaged") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.RijndaelManaged") or - isMethodCalledWithArg(e, "System.Security.Cryptography.CryptoConfig", "CreateFromName", 0, + isMethodCalledWithArg(e, "System.Security.Cryptography", "CryptoConfig", "CreateFromName", 0, "System.Security.Cryptography.SymmetricAlgorithm") // this creates Rijndael } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll index 0bd6461a6cd..54cc8d11864 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/security/cryptography/X509Certificates.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.security.Cryptography -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Security.Cryptography.X509Certificates` namespace. */ class SystemSecurityCryptographyX509CertificatesNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll index 6319ef6e894..cba035d28d3 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll @@ -4,7 +4,6 @@ import default import semmle.code.csharp.frameworks.system.Text -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Text.RegularExpressions` namespace. */ class SystemTextRegularExpressionsNamespace extends Namespace { @@ -37,7 +36,7 @@ class SystemTextRegularExpressionsRegexClass extends SystemTextRegularExpression */ class RegexGlobalTimeout extends MethodCall { RegexGlobalTimeout() { - this.getTarget().hasQualifiedName("System.AppDomain.SetData") and + this.getTarget().hasQualifiedName("System.AppDomain", "SetData") and this.getArgumentForName("name").getValue() = "REGEX_DEFAULT_MATCH_TIMEOUT" } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll index 7c0f1d2a885..acfc4edddd7 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/threading/Tasks.qll @@ -3,7 +3,6 @@ import csharp private import semmle.code.csharp.frameworks.system.Threading private import semmle.code.csharp.dataflow.internal.DataFlowPrivate -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Threading.Tasks` namespace. */ class SystemThreadingTasksNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll index 09d5e08d371..a059d5b3c7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.system.web.UI -private import semmle.code.csharp.dataflow.ExternalFlow /** The `System.Web.UI.WebControls` namespace. */ class SystemWebUIWebControlsNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/test/NUnit.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/test/NUnit.qll index ee6c50b2c8e..a1563ec2d46 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/test/NUnit.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/test/NUnit.qll @@ -2,6 +2,7 @@ import csharp import semmle.code.csharp.frameworks.Test +private import semmle.code.csharp.commons.QualifiedName /** A class that is an NUnit test fixture */ class NUnitFixture extends TestClass { @@ -38,7 +39,11 @@ class NUnitTestMethod extends TestMethod { expected.getTarget() = this | if expected.getArgument(0).getType() instanceof StringType - then result.hasQualifiedName(expected.getArgument(0).getValue()) + then + exists(string qualifier, string type | + result.hasQualifiedName(qualifier, type) and + splitQualifiedName(expected.getArgument(0).getValue(), qualifier, type) + ) else result = expected.getArgument(0).(TypeofExpr).getTypeAccess().getTarget() ) } @@ -56,11 +61,13 @@ class NUnitFile extends TestFile { /** An attribute of type `NUnit.Framework.ValueSourceAttribute`. */ class ValueSourceAttribute extends Attribute { - ValueSourceAttribute() { this.getType().hasQualifiedName("NUnit.Framework.ValueSourceAttribute") } + ValueSourceAttribute() { + this.getType().hasQualifiedName("NUnit.Framework", "ValueSourceAttribute") + } /** Holds if the first argument is the target type. */ private predicate typeSpecified() { - this.getArgument(0).getType().(Class).hasQualifiedName("System.Type") and + this.getArgument(0).getType().(Class).hasQualifiedName("System", "Type") and this.getArgument(1).getType() instanceof StringType } @@ -88,12 +95,12 @@ class ValueSourceAttribute extends Attribute { /** An attribute of type `NUnit.Framework.TestCaseSourceAttribute`. */ class TestCaseSourceAttribute extends Attribute { TestCaseSourceAttribute() { - this.getType().hasQualifiedName("NUnit.Framework.TestCaseSourceAttribute") + this.getType().hasQualifiedName("NUnit.Framework", "TestCaseSourceAttribute") } /** Holds if the first argument is the target type. */ private predicate typeSpecified() { - this.getArgument(0).getType().(Class).hasQualifiedName("System.Type") and + this.getArgument(0).getType().(Class).hasQualifiedName("System", "Type") and this.getArgument(1).getType() instanceof StringType } @@ -120,7 +127,7 @@ class TestCaseSourceAttribute extends Attribute { /** The `NUnit.Framework.Assert` class. */ class NUnitAssertClass extends Class { - NUnitAssertClass() { this.hasQualifiedName("NUnit.Framework.Assert") } + NUnitAssertClass() { this.hasQualifiedName("NUnit.Framework", "Assert") } /** Gets a `Null(object, ...)` method. */ Method getANullMethod() { @@ -179,5 +186,5 @@ class NUnitAssertClass extends Class { /** The `NUnit.Framework.AssertionException` class. */ class AssertionExceptionClass extends Class { - AssertionExceptionClass() { this.hasQualifiedName("NUnit.Framework.AssertionException") } + AssertionExceptionClass() { this.hasQualifiedName("NUnit.Framework", "AssertionException") } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/test/VisualStudio.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/test/VisualStudio.qll index 16f05cd7834..787c8770827 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/test/VisualStudio.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/test/VisualStudio.qll @@ -5,7 +5,7 @@ import semmle.code.csharp.frameworks.Test /** The `Microsoft.VisualStudio.TestTools.UnitTesting` namespace. */ class VSTestNamespace extends Namespace { - VSTestNamespace() { this.hasQualifiedName("Microsoft.VisualStudio.TestTools.UnitTesting") } + VSTestNamespace() { this.getFullName() = "Microsoft.VisualStudio.TestTools.UnitTesting" } } /** A class that contains test methods. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/test/XUnit.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/test/XUnit.qll index 0d229ad53ce..4d694774b7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/test/XUnit.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/test/XUnit.qll @@ -5,7 +5,7 @@ import semmle.code.csharp.frameworks.Test /** The `Xunit` namespace. */ class XUnitNamespace extends Namespace { - XUnitNamespace() { this.hasQualifiedName("Xunit") } + XUnitNamespace() { this.getFullName() = "Xunit" } } /** An xUnit test attribute. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CleartextStorageQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CleartextStorageQuery.qll index 0f241d0c69b..0ea33ca7590 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CleartextStorageQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CleartextStorageQuery.qll @@ -56,6 +56,4 @@ class ProtectSanitizer extends Sanitizer { /** * An external location sink. */ -class ExternalSink extends Sink { - ExternalSink() { this instanceof ExternalLocationSink } -} +class ExternalSink extends Sink instanceof ExternalLocationSink { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 758fbf50b16..4061ab8651c 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -38,14 +38,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** A source of local user input. */ -class LocalSource extends Source { - LocalSource() { this instanceof LocalFlowSource } -} +class LocalSource extends Source instanceof LocalFlowSource { } private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll index 506bf9599b7..82798a34743 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll @@ -36,9 +36,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A sink in `System.Diagnostic.Process` or its related classes. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index ac856264b15..e41a868be48 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -43,9 +43,7 @@ class Configuration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** The result of a reverse dns may be user-controlled. */ class ReverseDnsSource extends Source { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll index 11a79878698..2bf409899ee 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll @@ -39,6 +39,4 @@ private class PrivateDataSource extends Source { PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr } } -private class ExternalLocation extends Sink { - ExternalLocation() { this instanceof ExternalLocationSink } -} +private class ExternalLocation extends Sink instanceof ExternalLocationSink { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll index 4c0b7b00765..1fde874cc93 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -4,6 +4,7 @@ */ import csharp +private import semmle.code.csharp.commons.QualifiedName private import semmle.code.csharp.dataflow.flowsources.Remote private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.dataflow.FlowSummary @@ -16,8 +17,7 @@ abstract class SafeExternalApiCallable extends Callable { } /** DEPRECATED: Alias for SafeExternalApiCallable */ deprecated class SafeExternalAPICallable = SafeExternalApiCallable; -private class SummarizedCallableSafe extends SafeExternalApiCallable { - SummarizedCallableSafe() { this instanceof SummarizedCallable } +private class SummarizedCallableSafe extends SafeExternalApiCallable instanceof SummarizedCallable { } /** The default set of "safe" external APIs. */ @@ -70,8 +70,21 @@ class ExternalApiDataNode extends DataFlow::Node { /** Gets the index which is passed untrusted data (where -1 indicates the qualifier). */ int getIndex() { result = i } - /** Gets the description of the callable being called. */ - string getCallableDescription() { result = this.getCallable().getQualifiedName() } + /** Holds if the callable being use has name `name` and has qualifier `qualifier`. */ + predicate hasQualifiedName(string qualifier, string name) { + this.getCallable().hasQualifiedName(qualifier, name) + } + + /** + * DEPRECATED: Use hasQualifiedName/2 instead. + * + * Gets the description of the callable being called. + */ + deprecated string getCallableDescription() { + exists(string qualifier, string name | + this.hasQualifiedName(qualifier, name) and result = getQualifiedName(qualifier, name) + ) + } } /** DEPRECATED: Alias for ExternalApiDataNode */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 6f985463763..fb94273ccd7 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * An argument that sets the `Path` property of a `DirectoryEntry` object that is a sink for LDAP diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index 9320975c4d5..8764ebfd1d0 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -private class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +private class RemoteSource extends Source instanceof RemoteFlowSource { } private class HtmlSanitizer extends Sanitizer { HtmlSanitizer() { this.asExpr() instanceof HtmlSanitizedExpr } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll index e39cf1f0c44..47de109168d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/MissingXMLValidationQuery.qll @@ -43,9 +43,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * The input argument to a call to `XmlReader.Create` where the input will not be validated against diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll index e799501af4e..c3450946eb2 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll @@ -38,9 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * An expression that represents a regular expression with potential exponential behavior. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll index 7631375eba5..bfd0bcb5aea 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/RegexInjectionQuery.qll @@ -37,9 +37,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A `pattern` argument to a construction of a `Regex`. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll index cfcdd93aaa3..fee371359fd 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ResourceInjectionQuery.qll @@ -37,14 +37,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** A source of local user input. */ -class LocalSource extends Source { - LocalSource() { this instanceof LocalFlowSource } -} +class LocalSource extends Source instanceof LocalFlowSource { } /** An argument to the `ConnectionString` property on a data connection class. */ class SqlConnectionStringSink extends Sink { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll index f4184a391b9..d19b4739fde 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll @@ -38,14 +38,10 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** A source of local user input. */ -class LocalSource extends Source { - LocalSource() { this instanceof LocalFlowSource } -} +class LocalSource extends Source instanceof LocalFlowSource { } /** An SQL expression passed to an API call that executes SQL. */ class SqlInjectionExprSink extends Sink { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll index 0379173578e..7e9f266a310 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/TaintedPathQuery.qll @@ -39,9 +39,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A path argument to a `File` method call. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 6f75a712386..046424397e6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -44,9 +44,7 @@ abstract private class ConstructorOrStaticMethodSink extends Sink { } */ abstract class Sanitizer extends DataFlow::Node { } -private class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +private class RemoteSource extends Source instanceof RemoteFlowSource { } /** * User input to object method call deserialization flow tracking. @@ -162,7 +160,7 @@ class TaintToObjectTypeTrackingConfig extends TaintTracking2::Configuration { override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodCall mc, Method m | m = mc.getTarget() and - m.getDeclaringType().hasQualifiedName("System.Type") and + m.getDeclaringType().hasQualifiedName("System", "Type") and m.hasName("GetType") and m.isStatic() and n1.asExpr() = mc.getArgument(0) and diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index 796bc9f3b5d..499ff5c4a09 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -50,9 +50,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A URL argument to a call to `HttpResponse.Redirect()` or `Controller.Redirect()`, that is a diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll index 28317c0b201..ea5a16b6aaf 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XMLEntityInjectionQuery.qll @@ -14,9 +14,7 @@ private import semmle.code.csharp.security.Sanitizers */ abstract class Source extends DataFlow::Node { } -private class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +private class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A data flow sink for untrusted user input used in XML processing. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll index 7b062288f9c..f6f02fcd426 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XPathInjectionQuery.qll @@ -37,9 +37,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** The `xpath` argument to an `XPathExpression.Compile(..)` call. */ class XPathExpressionCompileSink extends Sink { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll index a216ce5e9d2..72a1d930354 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll @@ -149,9 +149,7 @@ class TaintTrackingConfiguration extends TaintTracking2::Configuration { } /** A source of remote user input. */ -private class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +private class RemoteSource extends Source instanceof RemoteFlowSource { } private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll index 637c3c29f8b..0232d9462e2 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll @@ -27,9 +27,7 @@ private class ExternalXssSink extends Sink { ExternalXssSink() { sinkNode(this, "xss") } } -private class HtmlSinkSink extends Sink { - HtmlSinkSink() { this instanceof HtmlSink } - +private class HtmlSinkSink extends Sink instanceof HtmlSink { override string explanation() { this instanceof WebPageWriteLiteralSink and result = "System.Web.WebPages.WebPage.WriteLiteral() method" diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll index 99f001eb115..de5a5bbd837 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll @@ -46,7 +46,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { class ArchiveFullNameSource extends Source { ArchiveFullNameSource() { exists(PropertyAccess pa | this.asExpr() = pa | - pa.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression.ZipArchiveEntry") and + pa.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression", "ZipArchiveEntry") and pa.getTarget().getName() = "FullName" ) } @@ -56,7 +56,7 @@ class ArchiveFullNameSource extends Source { class ExtractToFileArgSink extends Sink { ExtractToFileArgSink() { exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.Compression.ZipFileExtensions", "ExtractToFile") and + mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFileExtensions", "ExtractToFile") and this.asExpr() = mc.getArgumentForName("destinationFileName") ) } @@ -66,9 +66,9 @@ class ExtractToFileArgSink extends Sink { class FileOpenArgSink extends Sink { FileOpenArgSink() { exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.File", "Open") or - mc.getTarget().hasQualifiedName("System.IO.File", "OpenWrite") or - mc.getTarget().hasQualifiedName("System.IO.File", "Create") + mc.getTarget().hasQualifiedName("System.IO", "File", "Open") or + mc.getTarget().hasQualifiedName("System.IO", "File", "OpenWrite") or + mc.getTarget().hasQualifiedName("System.IO", "File", "Create") | this.asExpr() = mc.getArgumentForName("path") ) @@ -79,7 +79,7 @@ class FileOpenArgSink extends Sink { class FileStreamArgSink extends Sink { FileStreamArgSink() { exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.FileStream") + oc.getTarget().getDeclaringType().hasQualifiedName("System.IO", "FileStream") | this.asExpr() = oc.getArgumentForName("path") ) @@ -94,7 +94,7 @@ class FileStreamArgSink extends Sink { class FileInfoArgSink extends Sink { FileInfoArgSink() { exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.FileInfo") + oc.getTarget().getDeclaringType().hasQualifiedName("System.IO", "FileInfo") | this.asExpr() = oc.getArgumentForName("fileName") ) @@ -108,7 +108,7 @@ class FileInfoArgSink extends Sink { */ class GetFileNameSanitizer extends Sanitizer { GetFileNameSanitizer() { - exists(MethodCall mc | mc.getTarget().hasQualifiedName("System.IO.Path", "GetFileName") | + exists(MethodCall mc | mc.getTarget().hasQualifiedName("System.IO", "Path", "GetFileName") | this.asExpr() = mc ) } @@ -122,19 +122,19 @@ class GetFileNameSanitizer extends Sanitizer { */ class SubstringSanitizer extends Sanitizer { SubstringSanitizer() { - exists(MethodCall mc | mc.getTarget().hasQualifiedName("System.String", "Substring") | + exists(MethodCall mc | mc.getTarget().hasQualifiedName("System", "String", "Substring") | this.asExpr() = mc ) } } private predicate stringCheckGuard(Guard g, Expr e, AbstractValue v) { - g.(MethodCall).getTarget().hasQualifiedName("System.String", "StartsWith") and + g.(MethodCall).getTarget().hasQualifiedName("System", "String", "StartsWith") and g.(MethodCall).getQualifier() = e and // A StartsWith check against Path.Combine is not sufficient, because the ".." elements have // not yet been resolved. not exists(MethodCall combineCall | - combineCall.getTarget().hasQualifiedName("System.IO.Path", "Combine") and + combineCall.getTarget().hasQualifiedName("System.IO", "Path", "Combine") and DataFlow::localExprFlow(combineCall, e) ) and v.(AbstractValues::BooleanValue).getValue() = true diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll index 293d15b7461..6243074cf17 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll @@ -12,6 +12,7 @@ private import semmle.code.csharp.frameworks.system.web.ui.WebControls private import semmle.code.csharp.frameworks.WCF private import semmle.code.csharp.frameworks.microsoft.Owin private import semmle.code.csharp.frameworks.microsoft.AspNetCore +private import semmle.code.csharp.dataflow.ExternalFlow /** A data flow source of remote user input. */ abstract class RemoteFlowSource extends DataFlow::Node { @@ -19,6 +20,13 @@ abstract class RemoteFlowSource extends DataFlow::Node { abstract string getSourceType(); } +/** + * A module for importing frameworks that defines remote flow sources. + */ +private module RemoteFlowSources { + private import semmle.code.csharp.frameworks.ServiceStack +} + /** A data flow source of remote user input (ASP.NET). */ abstract class AspNetRemoteFlowSource extends RemoteFlowSource { } @@ -254,3 +262,9 @@ class AspNetCoreActionMethodParameter extends AspNetCoreRemoteFlowSource, DataFl override string getSourceType() { result = "ASP.NET Core MVC action method parameter" } } + +private class ExternalRemoteFlowSource extends RemoteFlowSource { + ExternalRemoteFlowSource() { sourceNode(this, "remote") } + + override string getSourceType() { result = "external" } +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll index 53fe605b963..b83795b033a 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll @@ -47,7 +47,7 @@ abstract class InsecureXmlProcessing extends Call { */ private predicate isSafeXmlResolver(Expr e) { e instanceof NullLiteral or - e.getType().(RefType).hasQualifiedName("System.Xml.XmlSecureResolver") + e.getType().(RefType).hasQualifiedName("System.Xml", "XmlSecureResolver") } /** @@ -94,7 +94,7 @@ module XmlSettings { * Holds if the given object creation constructs `XmlReaderSettings` with an insecure resolver. */ predicate insecureResolverSettings(ObjectCreation creation, Expr evidence, string reason) { - creation.getObjectType().getQualifiedName() = "System.Xml.XmlReaderSettings" and + creation.getObjectType().hasQualifiedName("System.Xml", "XmlReaderSettings") and ( // one unsafe assignment to XmlResolver exists(Expr xmlResolverVal | xmlResolverVal = getAValueForProp(creation, "XmlResolver") | @@ -114,7 +114,7 @@ module XmlSettings { * Holds if the given object creation constructs `XmlReaderSettings` with DTD processing enabled. */ predicate dtdEnabledSettings(ObjectCreation creation, Expr evidence, string reason) { - creation.getObjectType().getQualifiedName() = "System.Xml.XmlReaderSettings" and + creation.getObjectType().hasQualifiedName("System.Xml", "XmlReaderSettings") and ( exists(Expr dtdVal | dtdVal = getAValueForProp(creation, "DtdProcessing") | not isSafeDtdSetting(dtdVal) and evidence = dtdVal @@ -145,14 +145,16 @@ module XmlReader { private import semmle.code.csharp.dataflow.DataFlow2 private class InsecureXmlReaderCreate extends InsecureXmlProcessing, MethodCall { - InsecureXmlReaderCreate() { this.getTarget().hasQualifiedName("System.Xml.XmlReader.Create") } + InsecureXmlReaderCreate() { + this.getTarget().hasQualifiedName("System.Xml.XmlReader", "Create") + } /** * Gets the `XmlReaderSettings` argument to to this call, if any. */ Expr getSettings() { result = this.getAnArgument() and - result.getType().(RefType).getABaseType*().hasQualifiedName("System.Xml.XmlReaderSettings") + result.getType().(RefType).getABaseType*().hasQualifiedName("System.Xml", "XmlReaderSettings") } override predicate isUnsafe(string reason) { @@ -197,7 +199,7 @@ module XmlReader { .getType() .(RefType) .getABaseType*() - .hasQualifiedName("System.Xml.XmlReaderSettings") + .hasQualifiedName("System.Xml", "XmlReaderSettings") } override predicate isSink(DataFlow::Node sink) { @@ -209,7 +211,7 @@ module XmlReader { /** Provides predicates related to `System.Xml.XmlTextReader`. */ module XmlTextReader { private class InsecureXmlTextReader extends InsecureXmlProcessing, ObjectCreation { - InsecureXmlTextReader() { this.getObjectType().hasQualifiedName("System.Xml.XmlTextReader") } + InsecureXmlTextReader() { this.getObjectType().hasQualifiedName("System.Xml", "XmlTextReader") } override predicate isUnsafe(string reason) { not exists(Expr xmlResolverVal | @@ -244,8 +246,8 @@ module XmlDocument { */ class InsecureXmlDocument extends InsecureXmlProcessing, MethodCall { InsecureXmlDocument() { - this.getTarget().hasQualifiedName("System.Xml.XmlDocument.Load") or - this.getTarget().hasQualifiedName("System.Xml.XmlDocument.LoadXml") + this.getTarget().hasQualifiedName("System.Xml", "XmlDocument", "Load") or + this.getTarget().hasQualifiedName("System.Xml", "XmlDocument", "LoadXml") } override predicate isUnsafe(string reason) { diff --git a/csharp/ql/lib/semmle/code/csharp/serialization/Deserializers.qll b/csharp/ql/lib/semmle/code/csharp/serialization/Deserializers.qll index 8e026f03a0f..af3cdfc28bb 100644 --- a/csharp/ql/lib/semmle/code/csharp/serialization/Deserializers.qll +++ b/csharp/ql/lib/semmle/code/csharp/serialization/Deserializers.qll @@ -90,7 +90,7 @@ private class WrapperDeserializer extends UnsafeDeserializer { /** BinaryFormatter */ private class BinaryFormatterClass extends Class { BinaryFormatterClass() { - this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter") + this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary", "BinaryFormatter") } } @@ -121,7 +121,7 @@ class BinaryFormatterUnsafeDeserializeMethodResponseMethod extends Method, Unsaf /** SoapFormatter */ private class SoapFormatterClass extends Class { SoapFormatterClass() { - this.hasQualifiedName("System.Runtime.Serialization.Formatters.Soap.SoapFormatter") + this.hasQualifiedName("System.Runtime.Serialization.Formatters.Soap", "SoapFormatter") } } @@ -135,7 +135,7 @@ class SoapFormatterDeserializeMethod extends Method, UnsafeDeserializer { /** ObjectStateFormatter */ private class ObjectStateFormatterClass extends Class { - ObjectStateFormatterClass() { this.hasQualifiedName("System.Web.UI.ObjectStateFormatter") } + ObjectStateFormatterClass() { this.hasQualifiedName("System.Web.UI", "ObjectStateFormatter") } } /** `System.Web.UI.ObjectStateFormatter.Deserialize` method */ @@ -149,7 +149,7 @@ class ObjectStateFormatterDeserializeMethod extends Method, UnsafeDeserializer { /** NetDataContractSerializer */ class NetDataContractSerializerClass extends Class { NetDataContractSerializerClass() { - this.hasQualifiedName("System.Runtime.Serialization.NetDataContractSerializer") + this.hasQualifiedName("System.Runtime.Serialization", "NetDataContractSerializer") } } @@ -172,7 +172,7 @@ class NetDataContractSerializerReadObjectMethod extends Method, UnsafeDeserializ /** DataContractJsonSerializer */ class DataContractJsonSerializerClass extends Class { DataContractJsonSerializerClass() { - this.hasQualifiedName("System.Runtime.Serialization.Json.DataContractJsonSerializer") + this.hasQualifiedName("System.Runtime.Serialization.Json", "DataContractJsonSerializer") } } @@ -187,7 +187,7 @@ class DataContractJsonSerializerReadObjectMethod extends Method, UnsafeDeseriali /** JavaScriptSerializer */ class JavaScriptSerializerClass extends Class { JavaScriptSerializerClass() { - this.hasQualifiedName("System.Web.Script.Serialization.JavaScriptSerializer") + this.hasQualifiedName("System.Web.Script.Serialization", "JavaScriptSerializer") } } @@ -210,7 +210,7 @@ class JavaScriptSerializerClassDeserializeObjectMethod extends Method, UnsafeDes /** XmlObjectSerializer */ class XmlObjectSerializerClass extends Class { XmlObjectSerializerClass() { - this.hasQualifiedName("System.Runtime.Serialization.XmlObjectSerializer") + this.hasQualifiedName("System.Runtime.Serialization", "XmlObjectSerializer") } } @@ -224,7 +224,7 @@ class XmlObjectSerializerReadObjectMethod extends Method, UnsafeDeserializer { /** XmlSerializer */ class XmlSerializerClass extends Class { - XmlSerializerClass() { this.hasQualifiedName("System.Xml.Serialization.XmlSerializer") } + XmlSerializerClass() { this.hasQualifiedName("System.Xml.Serialization", "XmlSerializer") } } /** `System.Xml.Serialization.XmlSerializer.Deserialize` method */ @@ -238,7 +238,7 @@ class XmlSerializerDeserializeMethod extends Method, UnsafeDeserializer { /** DataContractSerializer */ class DataContractSerializerClass extends Class { DataContractSerializerClass() { - this.hasQualifiedName("System.Runtime.Serialization.DataContractSerializer") + this.hasQualifiedName("System.Runtime.Serialization", "DataContractSerializer") } } @@ -252,7 +252,7 @@ class DataContractSerializerReadObjectMethod extends Method, UnsafeDeserializer /** XmlMessageFormatter */ class XmlMessageFormatterClass extends Class { - XmlMessageFormatterClass() { this.hasQualifiedName("System.Messaging.XmlMessageFormatter") } + XmlMessageFormatterClass() { this.hasQualifiedName("System.Messaging", "XmlMessageFormatter") } } /** `System.Messaging.XmlMessageFormatter.Read` method */ @@ -265,7 +265,7 @@ class XmlMessageFormatterReadMethod extends Method, UnsafeDeserializer { /** LosFormatter */ private class LosFormatterClass extends Class { - LosFormatterClass() { this.hasQualifiedName("System.Web.UI.LosFormatter") } + LosFormatterClass() { this.hasQualifiedName("System.Web.UI", "LosFormatter") } } /** `System.Web.UI.LosFormatter.Deserialize` method */ @@ -278,7 +278,7 @@ class LosFormatterDeserializeMethod extends Method, UnsafeDeserializer { /** fastJSON */ private class FastJsonClass extends Class { - FastJsonClass() { this.hasQualifiedName("fastJSON.JSON") } + FastJsonClass() { this.hasQualifiedName("fastJSON", "JSON") } } /** `fastJSON.JSON.ToObject` method */ @@ -292,7 +292,7 @@ class FastJsonClassToObjectMethod extends Method, UnsafeDeserializer { /** Activity */ private class ActivityClass extends Class { - ActivityClass() { this.hasQualifiedName("System.Workflow.ComponentModel.Activity") } + ActivityClass() { this.hasQualifiedName("System.Workflow.ComponentModel", "Activity") } } /** `System.Workflow.ComponentModel.Activity.Load` method */ @@ -305,7 +305,7 @@ class ActivityLoadMethod extends Method, UnsafeDeserializer { /** ResourceReader */ private class ResourceReaderClass extends Class { - ResourceReaderClass() { this.hasQualifiedName("System.Resources.ResourceReader") } + ResourceReaderClass() { this.hasQualifiedName("System.Resources", "ResourceReader") } } /** `System.Resources.ResourceReader` constructor */ @@ -318,7 +318,9 @@ class ResourceReaderConstructor extends Constructor, UnsafeDeserializer { /** BinaryMessageFormatter */ private class BinaryMessageFormatterClass extends Class { - BinaryMessageFormatterClass() { this.hasQualifiedName("System.Messaging.BinaryMessageFormatter") } + BinaryMessageFormatterClass() { + this.hasQualifiedName("System.Messaging", "BinaryMessageFormatter") + } } /** `System.Messaging.BinaryMessageFormatter.Read` method */ @@ -331,7 +333,7 @@ class BinaryMessageFormatterReadMethod extends Method, UnsafeDeserializer { /** XamlReader */ private class XamlReaderClass extends Class { - XamlReaderClass() { this.hasQualifiedName("System.Windows.Markup.XamlReader") } + XamlReaderClass() { this.hasQualifiedName("System.Windows.Markup", "XamlReader") } } /** `System.Windows.Markup.XamlReader.Parse` method */ @@ -362,7 +364,7 @@ class XamlReaderLoadAsyncMethod extends Method, UnsafeDeserializer { /** ProxyObject */ private class ProxyObjectClass extends Class { - ProxyObjectClass() { this.hasQualifiedName("Microsoft.Web.Design.Remote.ProxyObject") } + ProxyObjectClass() { this.hasQualifiedName("Microsoft.Web.Design.Remote", "ProxyObject") } } /** `Microsoft.Web.Design.Remote.ProxyObject.DecodeValue` method */ @@ -383,7 +385,7 @@ class ProxyObjectDecodeSerializedObjectMethod extends Method, UnsafeDeserializer /** SweetJayson */ private class JaysonConverterClass extends Class { - JaysonConverterClass() { this.hasQualifiedName("Sweet.Jayson.JaysonConverter") } + JaysonConverterClass() { this.hasQualifiedName("Sweet.Jayson", "JaysonConverter") } } /** `Sweet.Jayson.JaysonConverter.ToObject` method */ @@ -398,7 +400,7 @@ class JaysonConverterToObjectMethod extends Method, UnsafeDeserializer { /** ServiceStack.Text.JsonSerializer */ private class ServiceStackTextJsonSerializerClass extends Class { ServiceStackTextJsonSerializerClass() { - this.hasQualifiedName("ServiceStack.Text.JsonSerializer") + this.hasQualifiedName("ServiceStack.Text", "JsonSerializer") } } @@ -432,7 +434,7 @@ class ServiceStackTextJsonSerializerDeserializeFromStreamMethod extends Method, /** ServiceStack.Text.TypeSerializer */ private class ServiceStackTextTypeSerializerClass extends Class { ServiceStackTextTypeSerializerClass() { - this.hasQualifiedName("ServiceStack.Text.TypeSerializer") + this.hasQualifiedName("ServiceStack.Text", "TypeSerializer") } } @@ -465,7 +467,9 @@ class ServiceStackTextTypeSerializerDeserializeFromStreamMethod extends Method, /** ServiceStack.Text.CsvSerializer */ private class ServiceStackTextCsvSerializerClass extends Class { - ServiceStackTextCsvSerializerClass() { this.hasQualifiedName("ServiceStack.Text.CsvSerializer") } + ServiceStackTextCsvSerializerClass() { + this.hasQualifiedName("ServiceStack.Text", "CsvSerializer") + } } /** `ServiceStack.Text.CsvSerializer.DeserializeFromString` method */ @@ -497,7 +501,9 @@ class ServiceStackTextCsvSerializerDeserializeFromStreamMethod extends Method, U /** ServiceStack.Text.XmlSerializer */ private class ServiceStackTextXmlSerializerClass extends Class { - ServiceStackTextXmlSerializerClass() { this.hasQualifiedName("ServiceStack.Text.XmlSerializer") } + ServiceStackTextXmlSerializerClass() { + this.hasQualifiedName("ServiceStack.Text", "XmlSerializer") + } } /** `ServiceStack.Text.XmlSerializer.DeserializeFromString` method */ @@ -529,7 +535,7 @@ class ServiceStackTextXmlSerializerDeserializeFromStreamMethod extends Method, U /** MBrace.FsPickler.FsPicklerSerializer */ private class FsPicklerSerializerClass extends Class { - FsPicklerSerializerClass() { this.hasQualifiedName("MBrace.FsPickler.FsPicklerSerializer") } + FsPicklerSerializerClass() { this.hasQualifiedName("MBrace.FsPickler", "FsPicklerSerializer") } } /** `MBrace.FsPickler.FsPicklerSerializer.Deserialize` method */ @@ -598,7 +604,7 @@ class FsPicklerSerializerClassUnPickleUntypedMethod extends Method, UnsafeDeseri /** MBrace.CsPickler.CsPicklerSerializer */ private class CsPicklerSerializerClass extends Class { - CsPicklerSerializerClass() { this.hasQualifiedName("MBrace.CsPickler.CsPicklerSerializer") } + CsPicklerSerializerClass() { this.hasQualifiedName("MBrace.CsPickler", "CsPicklerSerializer") } } /** `MBrace.FsPickler.CsPicklerSerializer.Deserialize` method */ @@ -620,7 +626,7 @@ class CsPicklerSerializerClassUnPickleMethod extends Method, UnsafeDeserializer /** MBrace.CsPickler.CsPicklerTextSerializer */ private class CsPicklerTextSerializerClass extends Class { CsPicklerTextSerializerClass() { - this.hasQualifiedName("MBrace.CsPickler.CsPicklerTextSerializer") + this.hasQualifiedName("MBrace.CsPickler", "CsPicklerTextSerializer") } } @@ -634,7 +640,7 @@ class CsPicklerSerializerClassUnPickleOfStringMethod extends Method, UnsafeDeser /** Polenter.Serialization.SharpSerializer */ private class SharpSerializerClass extends Class { - SharpSerializerClass() { this.hasQualifiedName("Polenter.Serialization.SharpSerializer") } + SharpSerializerClass() { this.hasQualifiedName("Polenter.Serialization", "SharpSerializer") } } /** `Polenter.Serialization.SharpSerializer.Deserialize` method */ @@ -647,7 +653,9 @@ class SharpSerializerClassDeserializeMethod extends Method, UnsafeDeserializer { /** YamlDotNet.Serialization.Deserializer */ private class YamlDotNetDeserializerClass extends Class { - YamlDotNetDeserializerClass() { this.hasQualifiedName("YamlDotNet.Serialization.Deserializer") } + YamlDotNetDeserializerClass() { + this.hasQualifiedName("YamlDotNet.Serialization", "Deserializer") + } } /** `YamlDotNet.Serialization.Deserializer.Deserialize` method */ diff --git a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll index 046cb99944e..fea5a1aaeca 100644 --- a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll +++ b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll @@ -4,11 +4,15 @@ import Element import Type +private import semmle.code.csharp.commons.QualifiedName /** A declaration. */ class Declaration extends NamedElement, @dotnet_declaration { override predicate hasQualifiedName(string qualifier, string name) { - qualifier = this.getDeclaringType().getQualifiedName() and + exists(string dqualifier, string dname | + this.getDeclaringType().hasQualifiedName(dqualifier, dname) and + qualifier = getQualifiedName(dqualifier, dname) + ) and name = this.getName() } @@ -75,6 +79,16 @@ class Member extends Declaration, @dotnet_member { /** Holds if this member is `static`. */ predicate isStatic() { none() } + + /** + * Holds if this member has name `name` and is defined in type `type` + * with namespace `namespace`. + */ + cached + predicate hasQualifiedName(string namespace, string type, string name) { + this.getDeclaringType().hasQualifiedName(namespace, type) and + name = this.getName() + } } /** A property. */ diff --git a/csharp/ql/lib/semmle/code/dotnet/Element.qll b/csharp/ql/lib/semmle/code/dotnet/Element.qll index 713261dcf36..1000ce57666 100644 --- a/csharp/ql/lib/semmle/code/dotnet/Element.qll +++ b/csharp/ql/lib/semmle/code/dotnet/Element.qll @@ -97,10 +97,13 @@ class NamedElement extends Element, @dotnet_named_element { } /** + * DEPRECATED: Use `hasQualifiedName/2` instead. * Holds if this element has qualified name `qualifiedName`, for example * `System.Console.WriteLine`. */ - final predicate hasQualifiedName(string qualifiedName) { qualifiedName = this.getQualifiedName() } + deprecated final predicate hasQualifiedName(string qualifiedName) { + qualifiedName = this.getQualifiedName() + } /** Holds if this element has the qualified name `qualifier`.`name`. */ cached diff --git a/csharp/ql/lib/semmle/code/dotnet/Namespace.qll b/csharp/ql/lib/semmle/code/dotnet/Namespace.qll index 9a0e9edac00..31a625de062 100644 --- a/csharp/ql/lib/semmle/code/dotnet/Namespace.qll +++ b/csharp/ql/lib/semmle/code/dotnet/Namespace.qll @@ -3,6 +3,7 @@ */ private import Declaration +private import semmle.code.csharp.commons.QualifiedName /** A namespace. */ class Namespace extends Declaration, @namespace { @@ -25,12 +26,15 @@ class Namespace extends Declaration, @namespace { * `qualifier`=`System.Collections` and `name`=`Generic`. */ override predicate hasQualifiedName(string qualifier, string name) { - qualifier = this.getParentNamespace().getQualifiedName() and + exists(string pqualifier, string pname | + this.getParentNamespace().hasQualifiedName(pqualifier, pname) and + qualifier = getQualifiedName(pqualifier, pname) + ) and name = this.getName() } /** Gets a textual representation of this namespace. */ - override string toString() { result = this.getQualifiedName() } + override string toString() { result = this.getFullName() } /** Holds if this is the global namespace. */ final predicate isGlobalNamespace() { this.getName() = "" } @@ -41,6 +45,16 @@ class Namespace extends Declaration, @namespace { final override string getUndecoratedName() { namespaces(this, result) } override string getAPrimaryQlClass() { result = "Namespace" } + + /** + * Get the fully qualified name of this namespace. + */ + string getFullName() { + exists(string namespace, string name | + this.hasQualifiedName(namespace, name) and + result = getQualifiedName(namespace, name) + ) + } } /** The global namespace. */ diff --git a/csharp/ql/lib/semmle/code/dotnet/Type.qll b/csharp/ql/lib/semmle/code/dotnet/Type.qll index 04b6cdaf6eb..ab55f284824 100644 --- a/csharp/ql/lib/semmle/code/dotnet/Type.qll +++ b/csharp/ql/lib/semmle/code/dotnet/Type.qll @@ -28,7 +28,7 @@ class ValueOrRefType extends Type, @dotnet_valueorreftype { or if this.getDeclaringNamespace().isGlobalNamespace() then result = "" - else result = this.getDeclaringNamespace().getQualifiedName() + "." + else result = this.getDeclaringNamespace().getFullName() + "." } pragma[noinline] diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index 4ac7d8bcac6..83aca6b3e4f 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -1134,6 +1134,9 @@ case @expr.kind of | 128 = @or_pattern_expr | 129 = @function_pointer_invocation_expr | 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr /* Preprocessor */ | 999 = @define_symbol_expr ; diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats index 2d1c330c7d2..c2017892642 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats @@ -948,6 +948,14 @@ @with_expr 101 + + @list_pattern_expr + 0 + + + @slice_pattern_expr + 0 + @xmldtd 40 diff --git a/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/old.dbscheme b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/old.dbscheme new file mode 100644 index 00000000000..4ac7d8bcac6 --- /dev/null +++ b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/old.dbscheme @@ -0,0 +1,2064 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/semmlecode.csharp.dbscheme b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..83aca6b3e4f --- /dev/null +++ b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/semmlecode.csharp.dbscheme @@ -0,0 +1,2067 @@ +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2021-07-14 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | f1.cs + * 3 | f2.cs + * 4 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +// Populated by the CSV extractor +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @externalDataElement + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function | @lambda_expr; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +files( + unique int id: @file, + string name: string ref); + +folders( + unique int id: @folder, + string name: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_global( + unique int id: @using_directive ref +); + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric, 3: span */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref); + +directive_line_offset( + unique int id: @directive_line ref, + int offset: int ref); + +directive_line_span( + unique int id: @directive_line ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int kind: int ref, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +case @attribute.kind of + 0 = @attribute_default +| 1 = @attribute_return +| 2 = @attribute_assembly +| 3 = @attribute_module +; + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +| 130 = @with_expr +/* C# 11.0 */ +| 131 = @list_pattern_expr +| 132 = @slice_pattern_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +lambda_expr_return_type( + unique int id: @lambda_expr ref, + int type_id: @type_or_ref ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/upgrade.properties b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/upgrade.properties new file mode 100644 index 00000000000..676f413d36d --- /dev/null +++ b/csharp/ql/lib/upgrades/4ac7d8bcac6f664b1e83c858aa71f8dc761cc603/upgrade.properties @@ -0,0 +1,2 @@ +description: Add list- and slice pattern expressions kinds. +compatibility: backwards diff --git a/csharp/ql/src/API Abuse/CallToGCCollect.ql b/csharp/ql/src/API Abuse/CallToGCCollect.ql index 4ffef9caa0a..a10e7dd238f 100644 --- a/csharp/ql/src/API Abuse/CallToGCCollect.ql +++ b/csharp/ql/src/API Abuse/CallToGCCollect.ql @@ -16,5 +16,5 @@ where c.getTarget() = gcCollect and gcCollect.hasName("Collect") and gcCollect.hasNoParameters() and - gcCollect.getDeclaringType().hasQualifiedName("System.GC") + gcCollect.getDeclaringType().hasQualifiedName("System", "GC") select c, "Call to 'GC.Collect()'." diff --git a/csharp/ql/src/API Abuse/NonOverridingMethod.ql b/csharp/ql/src/API Abuse/NonOverridingMethod.ql index 002835db5a9..4d499a09b8c 100644 --- a/csharp/ql/src/API Abuse/NonOverridingMethod.ql +++ b/csharp/ql/src/API Abuse/NonOverridingMethod.ql @@ -11,6 +11,7 @@ */ import csharp +import semmle.code.csharp.commons.QualifiedName private predicate potentialOverride(Method vm, Method m) { vm.getDeclaringType() = m.getDeclaringType().getBaseClass+() @@ -36,9 +37,10 @@ predicate nonOverridingMethod(Method m, Method vm) { m.getName().toLowerCase() = vm.getName().toLowerCase() } -from Method m, Method vm +from Method m, Method vm, string namespace, string type, string name where m.fromSource() and - nonOverridingMethod(m, vm) + nonOverridingMethod(m, vm) and + vm.hasQualifiedName(namespace, type, name) select m, "Method '" + m.getName() + "' looks like it should override $@ but does not do so.", - vm.getUnboundDeclaration(), vm.getQualifiedName() + vm.getUnboundDeclaration(), getQualifiedName(namespace, type, name) diff --git a/csharp/ql/src/AlertSuppression.ql b/csharp/ql/src/AlertSuppression.ql index 3cb6d759b6e..cfa8dbae832 100644 --- a/csharp/ql/src/AlertSuppression.ql +++ b/csharp/ql/src/AlertSuppression.ql @@ -44,9 +44,7 @@ class SuppressionComment extends CommentLine { /** * The scope of an alert suppression comment. */ -class SuppressionScope extends @commentline { - SuppressionScope() { this instanceof SuppressionComment } - +class SuppressionScope extends @commentline instanceof SuppressionComment { /** Gets a suppression comment with this scope. */ SuppressionComment getSuppressionComment() { result = this } @@ -60,7 +58,7 @@ class SuppressionScope extends @commentline { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) + super.covers(filepath, startline, startcolumn, endline, endcolumn) } /** Gets a textual representation of this element. */ diff --git a/csharp/ql/src/Bad Practices/LeftoverDebugCode.ql b/csharp/ql/src/Bad Practices/LeftoverDebugCode.ql index c4fdee86eb8..d2cee805c04 100644 --- a/csharp/ql/src/Bad Practices/LeftoverDebugCode.ql +++ b/csharp/ql/src/Bad Practices/LeftoverDebugCode.ql @@ -19,6 +19,6 @@ where m.fromSource() and exists(UsingNamespaceDirective u | u.getFile() = m.getFile() and - u.getImportedNamespace().hasQualifiedName("System.Web") + u.getImportedNamespace().hasQualifiedName("System", "Web") ) select m, "Remove debug code if your ASP.NET application is in production." diff --git a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll index b65cdcd1961..73b82c14700 100644 --- a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll +++ b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll @@ -10,26 +10,26 @@ private predicate trivialPositiveIntValue(string s) { s = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", - "17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", - "16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127", - "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", - "4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", - "0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", - "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", - "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", - "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", - "0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007", - "0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", - "0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", - "0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", - "0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", - "0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", - "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", - "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f", - "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", - "0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", - "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000", - "10000", "100000", "1000000", "10000000", "100000000", "1000000000" + "17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", + "32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511", + "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295", + "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020", + "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", + "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", + "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", + "0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", + "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", + "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", + "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", + "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", + "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010", + "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000", + "0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", + "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x02", + "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x01", "0x03", "0x07", "0x0f", "0x1f", + "0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000", + "100000000", "1000000000" ] } diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql index 4cc4f58bdba..3e87b71253d 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql +++ b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql @@ -11,90 +11,95 @@ import csharp -string prefix(string typename) { - typename = "System.Web.UI.WebControls.Label" and result = "lbl" +string prefix(string qualifier, string typename) { + qualifier = "System.Web.UI.WebControls" and + ( + typename = "Label" and result = "lbl" + or + typename = "TextBox" and result = "txt" + or + typename = ["Button", "LinkButton"] and result = "btn" + or + typename = "ImageButton" and result = "ibtn" + or + typename = "Hyperlink" and result = "hpl" + or + typename = "DropDownList" and result = "cmb" + or + typename = "ListBox" and result = "lst" + or + typename = "Datagrid" and result = "dgr" + or + typename = "Datalist" and result = "dtl" + or + typename = "Repeater" and result = "rpt" + or + typename = "CheckBox" and result = "chk" + or + typename = "CheckBoxList" and result = "chklst" + or + typename = "RadioButtonList" and result = "radlst" + or + typename = "RadioButton" and result = "rad" + or + typename = "Image" and result = "img" + or + typename = "Panel" and result = "pnl" + or + typename = "PlaceHolder" and result = "plh" + or + typename = "Calendar" and result = "cal" + or + typename = "AdRotator" and result = "adr" + or + typename = "Table" and result = "tbl" + or + typename = "RequiredFieldValidator" and result = "rfv" + or + typename = "CompareValidator" and result = "cmv" + or + typename = "RegularExpressionValidator" and result = "rev" + or + typename = "CustomValidator" and result = "csv" + or + typename = "ValidationSummary" and result = "vsm" + or + typename = "XML" and result = "xml" + or + typename = "Literal" and result = "lit" + or + typename = "Form" and result = "frm" + or + typename = "Frame" and result = "fra" + or + typename = "CrystalReportViewer" and result = "crvr" + ) or - typename = "System.Web.UI.WebControls.TextBox" and result = "txt" - or - typename = "System.Web.UI.WebControls.Button" and result = "btn" - or - typename = "System.Web.UI.WebControls.LinkButton" and result = "btn" - or - typename = "System.Web.UI.WebControls.ImageButton" and result = "ibtn" - or - typename = "System.Web.UI.WebControls.Hyperlink" and result = "hpl" - or - typename = "System.Web.UI.WebControls.DropDownList" and result = "cmb" - or - typename = "System.Web.UI.WebControls.ListBox" and result = "lst" - or - typename = "System.Web.UI.WebControls.Datagrid" and result = "dgr" - or - typename = "System.Web.UI.WebControls.Datalist" and result = "dtl" - or - typename = "System.Web.UI.WebControls.Repeater" and result = "rpt" - or - typename = "System.Web.UI.WebControls.CheckBox" and result = "chk" - or - typename = "System.Web.UI.WebControls.CheckBoxList" and result = "chklst" - or - typename = "System.Web.UI.WebControls.RadioButtonList" and result = "radlst" - or - typename = "System.Web.UI.WebControls.RadioButton" and result = "rad" - or - typename = "System.Web.UI.WebControls.Image" and result = "img" - or - typename = "System.Web.UI.WebControls.Panel" and result = "pnl" - or - typename = "System.Web.UI.WebControls.PlaceHolder" and result = "plh" - or - typename = "System.Web.UI.WebControls.Calendar" and result = "cal" - or - typename = "System.Web.UI.WebControls.AdRotator" and result = "adr" - or - typename = "System.Web.UI.WebControls.Table" and result = "tbl" - or - typename = "System.Web.UI.WebControls.RequiredFieldValidator" and result = "rfv" - or - typename = "System.Web.UI.WebControls.CompareValidator" and result = "cmv" - or - typename = "System.Web.UI.WebControls.RegularExpressionValidator" and result = "rev" - or - typename = "System.Web.UI.WebControls.CustomValidator" and result = "csv" - or - typename = "System.Web.UI.WebControls.ValidationSummary" and result = "vsm" - or - typename = "System.Web.UI.WebControls.XML" and result = "xml" - or - typename = "System.Web.UI.WebControls.Literal" and result = "lit" - or - typename = "System.Web.UI.WebControls.Form" and result = "frm" - or - typename = "System.Web.UI.WebControls.Frame" and result = "fra" - or - typename = "System.Web.UI.WebControls.CrystalReportViewer" and result = "crvr" - or - typename = "System.Web.UI.HtmlControls.TextArea" and result = "txa" - or - typename = "System.Web.UI.HtmlControls.FileField" and result = "fle" - or - typename = "System.Web.UI.HtmlControls.PasswordField" and result = "pwd" - or - typename = "System.Web.UI.HtmlControls.Hidden" and result = "hdn" - or - typename = "System.Web.UI.HtmlControls.Table" and result = "tbl" - or - typename = "System.Web.UI.HtmlControls.FlowLayoutPanel" and result = "flp" - or - typename = "System.Web.UI.HtmlControls.GridLayoutPanel" and result = "glp" - or - typename = "System.Web.UI.HtmlControls.HorizontalRule" and result = "hr" + qualifier = "System.Web.UI.HtmlControls" and + ( + typename = "TextArea" and result = "txa" + or + typename = "FileField" and result = "fle" + or + typename = "PasswordField" and result = "pwd" + or + typename = "Hidden" and result = "hdn" + or + typename = "Table" and result = "tbl" + or + typename = "FlowLayoutPanel" and result = "flp" + or + typename = "GridLayoutPanel" and result = "glp" + or + typename = "HorizontalRule" and result = "hr" + ) } -from Field f, RefType t, string name, string prefix +from Field f, RefType t, string name, string prefix, string qualifier, string type where f.getType() = t and f.getName() = name and - prefix = prefix(t.getQualifiedName()) and + t.hasQualifiedName(qualifier, type) and + prefix = prefix(qualifier, type) and not name.matches(prefix + "%") select f, "This field should have the prefix '" + prefix + "' to match its types." diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql index 2bf51653d99..53660128959 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql +++ b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql @@ -29,7 +29,7 @@ predicate usedInHumanWrittenCode(Field f) { from Field field, ValueOrRefType widget, string prefix where - widget.getABaseType*().hasQualifiedName("System.Windows.Forms.Control") and + widget.getABaseType*().hasQualifiedName("System.Windows.Forms", "Control") and field.getType() = widget and field.getName().regexpMatch(prefix + "[0-9]+") and controlName(prefix) and diff --git a/csharp/ql/src/Bad Practices/UseOfSystemOutputStream.ql b/csharp/ql/src/Bad Practices/UseOfSystemOutputStream.ql index 05424066c41..fbf9ea069ea 100644 --- a/csharp/ql/src/Bad Practices/UseOfSystemOutputStream.ql +++ b/csharp/ql/src/Bad Practices/UseOfSystemOutputStream.ql @@ -14,30 +14,30 @@ import semmle.code.csharp.commons.Util predicate isConsoleOutRedefinedSomewhere() { exists(MethodCall mc | mc.getTarget().hasName("SetOut") and - mc.getTarget().getDeclaringType().hasQualifiedName("System.Console") + mc.getTarget().getDeclaringType().hasQualifiedName("System", "Console") ) } predicate isConsoleErrorRedefinedSomewhere() { exists(MethodCall mc | mc.getTarget().hasName("SetError") and - mc.getTarget().getDeclaringType().hasQualifiedName("System.Console") + mc.getTarget().getDeclaringType().hasQualifiedName("System", "Console") ) } predicate isCallToConsoleWrite(MethodCall mc) { mc.getTarget().getName().matches("Write%") and - mc.getTarget().getDeclaringType().hasQualifiedName("System.Console") + mc.getTarget().getDeclaringType().hasQualifiedName("System", "Console") } predicate isAccessToConsoleOut(PropertyAccess pa) { pa.getTarget().hasName("Out") and - pa.getTarget().getDeclaringType().hasQualifiedName("System.Console") + pa.getTarget().getDeclaringType().hasQualifiedName("System", "Console") } predicate isAccessToConsoleError(PropertyAccess pa) { pa.getTarget().hasName("Error") and - pa.getTarget().getDeclaringType().hasQualifiedName("System.Console") + pa.getTarget().getDeclaringType().hasQualifiedName("System", "Console") } from Expr e diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 46be24580ef..8110355ef6a 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.6 + +No user-facing changes. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +No user-facing changes. + ## 0.4.3 No user-facing changes. diff --git a/csharp/ql/src/Concurrency/Concurrency.qll b/csharp/ql/src/Concurrency/Concurrency.qll index b2d5e97f28e..da14cfdb8e5 100644 --- a/csharp/ql/src/Concurrency/Concurrency.qll +++ b/csharp/ql/src/Concurrency/Concurrency.qll @@ -5,7 +5,7 @@ import csharp private class WaitCall extends MethodCall { WaitCall() { this.getTarget().hasName("Wait") and - this.getTarget().getDeclaringType().hasQualifiedName("System.Threading.Monitor") + this.getTarget().getDeclaringType().hasQualifiedName("System.Threading", "Monitor") } Expr getExpr() { result = this.getArgument(0) } @@ -30,12 +30,12 @@ class WaitStmt extends ExprStmt { private class SynchronizedMethodAttribute extends Attribute { SynchronizedMethodAttribute() { - this.getType().hasQualifiedName("System.Runtime.CompilerServices.MethodImplAttribute") and + this.getType().hasQualifiedName("System.Runtime.CompilerServices", "MethodImplAttribute") and exists(MemberConstantAccess a, MemberConstant mc | a = this.getArgument(0) and a.getTarget() = mc and mc.hasName("Synchronized") and - mc.getDeclaringType().hasQualifiedName("System.Runtime.CompilerServices.MethodImplOptions") + mc.getDeclaringType().hasQualifiedName("System.Runtime.CompilerServices", "MethodImplOptions") ) } } diff --git a/csharp/ql/src/Concurrency/ThreadCreation.qll b/csharp/ql/src/Concurrency/ThreadCreation.qll index 43cb9da20e6..3ef6726ef2f 100644 --- a/csharp/ql/src/Concurrency/ThreadCreation.qll +++ b/csharp/ql/src/Concurrency/ThreadCreation.qll @@ -9,14 +9,18 @@ import Concurrency */ class ThreadStartingCallable extends Callable { ThreadStartingCallable() { - this.(Constructor).getDeclaringType().getQualifiedName() = "System.Threading.Tasks.Task" or - this.(Method).getQualifiedName() = "System.Threading.Tasks.Task.Run" or - this.(Constructor).getDeclaringType().getQualifiedName() = "System.Threading.Thread" or - this.(Method).getQualifiedName() = "System.Threading.Thread.Start" or - this.(Constructor) - .getDeclaringType() - .getQualifiedName() - .matches("System.Threading.Tasks.Task<%>") + this.(Constructor).getDeclaringType().hasQualifiedName("System.Threading.Tasks", "Task") + or + this.(Method).hasQualifiedName("System.Threading.Tasks", "Task", "Run") + or + this.(Constructor).getDeclaringType().hasQualifiedName("System.Threading", "Thread") + or + this.(Method).hasQualifiedName("System.Threading", "Thread", "Start") + or + exists(string name | + this.(Constructor).getDeclaringType().hasQualifiedName("System.Threading.Tasks", name) and + name.matches("Task<%>") + ) } } diff --git a/csharp/ql/src/Dead Code/DeadCode.qll b/csharp/ql/src/Dead Code/DeadCode.qll index dd0f6104e31..0718312867f 100644 --- a/csharp/ql/src/Dead Code/DeadCode.qll +++ b/csharp/ql/src/Dead Code/DeadCode.qll @@ -26,7 +26,7 @@ Expr getAnAccessByDynamicCall(Method m) { exists(MethodCall mc, Method target | target = mc.getTarget() and target.hasName("InvokeMember") and - target.getDeclaringType().hasQualifiedName("System.Type") and + target.getDeclaringType().hasQualifiedName("System", "Type") and mc.getArgument(0).(StringLiteral).getValue() = m.getName() and mc.getArgument(3).getType().(RefType).hasMethod(m) and result = mc @@ -42,7 +42,7 @@ Expr getAMethodAccess(Method m) { predicate potentiallyAccessedByForEach(Method m) { m.hasName("GetEnumerator") and - m.getDeclaringType().getABaseType+().hasQualifiedName("System.Collections.IEnumerable") + m.getDeclaringType().getABaseType+().hasQualifiedName("System.Collections", "IEnumerable") or foreach_stmt_desugar(_, m, 1) } diff --git a/csharp/ql/src/Dead Code/DeadRefTypes.ql b/csharp/ql/src/Dead Code/DeadRefTypes.ql index f3949891271..d881e715f48 100644 --- a/csharp/ql/src/Dead Code/DeadRefTypes.ql +++ b/csharp/ql/src/Dead Code/DeadRefTypes.ql @@ -16,15 +16,13 @@ import semmle.code.csharp.frameworks.Test import semmle.code.csharp.metrics.Coupling predicate potentiallyUsedFromXaml(RefType t) { - exists(string name | name = t.getABaseType*().getQualifiedName() | - name = "System.Windows.Data.IValueConverter" or - name = "System.Windows.Data.IMultiValueConverter" - ) + t.getABaseType*() + .hasQualifiedName("System.Windows.Data", ["IValueConverter", "IMultiValueConverter"]) } class ExportAttribute extends Attribute { ExportAttribute() { - getType().hasQualifiedName("System.ComponentModel.Composition.ExportAttribute") + getType().hasQualifiedName("System.ComponentModel.Composition", "ExportAttribute") } } diff --git a/csharp/ql/src/Documentation/XmldocMissingException.ql b/csharp/ql/src/Documentation/XmldocMissingException.ql index a5c06c598c7..94cd5e96e33 100644 --- a/csharp/ql/src/Documentation/XmldocMissingException.ql +++ b/csharp/ql/src/Documentation/XmldocMissingException.ql @@ -10,6 +10,7 @@ */ import Documentation +import semmle.code.csharp.commons.QualifiedName from SourceMethodOrConstructor m, ThrowElement throw, RefType throwType where @@ -20,8 +21,15 @@ where comment = getADeclarationXmlComment(m) and exceptionName = comment.getCref(offset) and throwType.getABaseType*() = throwBaseType and - (throwBaseType.hasName(exceptionName) or throwBaseType.hasQualifiedName(exceptionName)) - // and comment.hasBody(offset) // Too slow + ( + throwBaseType.hasName(exceptionName) + or + exists(string qualifier, string type | + splitQualifiedName(exceptionName, qualifier, type) and + throwBaseType.hasQualifiedName(qualifier, type) + ) + // and comment.hasBody(offset) // Too slow + ) ) and not getADeclarationXmlComment(m) instanceof InheritDocXmlComment select m, "Exception $@ should be documented.", throw, throw.getExpr().getType().getName() diff --git a/csharp/ql/src/Likely Bugs/Collections/ContainerSizeCmpZero.ql b/csharp/ql/src/Likely Bugs/Collections/ContainerSizeCmpZero.ql index 23f786be49a..f281601a554 100644 --- a/csharp/ql/src/Likely Bugs/Collections/ContainerSizeCmpZero.ql +++ b/csharp/ql/src/Likely Bugs/Collections/ContainerSizeCmpZero.ql @@ -13,9 +13,9 @@ import csharp import semmle.code.csharp.commons.Assertions -private predicate propertyOverrides(Property p, string baseClass, string property) { +private predicate propertyOverrides(Property p, string qualifier, string baseClass, string property) { exists(Property p2 | - p2.getUnboundDeclaration().getDeclaringType().hasQualifiedName(baseClass) and + p2.getUnboundDeclaration().getDeclaringType().hasQualifiedName(qualifier, baseClass) and p2.hasName(property) | p.overridesOrImplementsOrEquals(p2) @@ -24,16 +24,16 @@ private predicate propertyOverrides(Property p, string baseClass, string propert private predicate containerSizeAccess(PropertyAccess pa, string containerKind) { ( - propertyOverrides(pa.getTarget(), "System.Collections.Generic.ICollection<>", "Count") or - propertyOverrides(pa.getTarget(), "System.Collections.Generic.IReadOnlyCollection<>", "Count") or - propertyOverrides(pa.getTarget(), "System.Collections.ICollection", "Count") + propertyOverrides(pa.getTarget(), "System.Collections.Generic", "ICollection<>", "Count") or + propertyOverrides(pa.getTarget(), "System.Collections.Generic", "IReadOnlyCollection<>", "Count") or + propertyOverrides(pa.getTarget(), "System.Collections", "ICollection", "Count") ) and containerKind = "a collection" or ( - propertyOverrides(pa.getTarget(), "System.String", "Length") and containerKind = "a string" + propertyOverrides(pa.getTarget(), "System", "String", "Length") and containerKind = "a string" or - propertyOverrides(pa.getTarget(), "System.Array", "Length") and containerKind = "an array" + propertyOverrides(pa.getTarget(), "System", "Array", "Length") and containerKind = "an array" ) } diff --git a/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql b/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql index 838406ab82e..814ccd99e4e 100644 --- a/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql +++ b/csharp/ql/src/Likely Bugs/LeapYear/UnsafeYearConstruction.ql @@ -20,14 +20,14 @@ class UnsafeYearCreationFromArithmeticConfiguration extends TaintTracking::Confi override predicate isSource(DataFlow::Node source) { exists(ArithmeticOperation ao, PropertyAccess pa | ao = source.asExpr() | pa = ao.getAChild*() and - pa.getProperty().hasQualifiedName("System.DateTime.Year") + pa.getProperty().hasQualifiedName("System.DateTime", "Year") ) } override predicate isSink(DataFlow::Node sink) { exists(ObjectCreation oc | sink.asExpr() = oc.getArgumentForName("year") and - oc.getObjectType().getABaseType*().hasQualifiedName("System.DateTime") + oc.getObjectType().getABaseType*().hasQualifiedName("System", "DateTime") ) } } diff --git a/csharp/ql/src/Likely Bugs/MishandlingJapaneseEra.ql b/csharp/ql/src/Likely Bugs/MishandlingJapaneseEra.ql index 0f4c5f0d1a0..6699f863631 100644 --- a/csharp/ql/src/Likely Bugs/MishandlingJapaneseEra.ql +++ b/csharp/ql/src/Likely Bugs/MishandlingJapaneseEra.ql @@ -23,8 +23,8 @@ predicate isEraStart(int year, int month, int day) { predicate isExactEraStartDateCreation(ObjectCreation cr) { ( - cr.getType().hasQualifiedName("System.DateTime") or - cr.getType().hasQualifiedName("System.DateTimeOffset") + cr.getType().hasQualifiedName("System", "DateTime") or + cr.getType().hasQualifiedName("System", "DateTimeOffset") ) and isEraStart(cr.getArgument(0).getValue().toInt(), cr.getArgument(1).getValue().toInt(), cr.getArgument(2).getValue().toInt()) @@ -32,8 +32,10 @@ predicate isExactEraStartDateCreation(ObjectCreation cr) { predicate isDateFromJapaneseCalendarToDateTime(MethodCall mc) { ( - mc.getQualifier().getType().hasQualifiedName("System.Globalization.JapaneseCalendar") or - mc.getQualifier().getType().hasQualifiedName("System.Globalization.JapaneseLunisolarCalendar") + mc.getQualifier().getType().hasQualifiedName("System.Globalization", "JapaneseCalendar") or + mc.getQualifier() + .getType() + .hasQualifiedName("System.Globalization", "JapaneseLunisolarCalendar") ) and mc.getTarget().hasName("ToDateTime") and mc.getArgument(0).hasValue() and @@ -47,16 +49,16 @@ predicate isDateFromJapaneseCalendarToDateTime(MethodCall mc) { predicate isDateFromJapaneseCalendarCreation(ObjectCreation cr) { ( - cr.getType().hasQualifiedName("System.DateTime") or - cr.getType().hasQualifiedName("System.DateTimeOffset") + cr.getType().hasQualifiedName("System", "DateTime") or + cr.getType().hasQualifiedName("System", "DateTimeOffset") ) and ( cr.getArgumentForName("calendar") .getType() - .hasQualifiedName("System.Globalization.JapaneseCalendar") or + .hasQualifiedName("System.Globalization", "JapaneseCalendar") or cr.getArgumentForName("calendar") .getType() - .hasQualifiedName("System.Globalization.JapaneseLunisolarCalendar") + .hasQualifiedName("System.Globalization", "JapaneseLunisolarCalendar") ) and cr.getArgumentForName("year").hasValue() } diff --git a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql index 392c3e843d7..16ddedd6400 100644 --- a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql +++ b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql @@ -19,7 +19,7 @@ import semmle.code.csharp.frameworks.system.collections.Generic class UnsafeField extends Field { UnsafeField() { this.isStatic() and - not this.getAnAttribute().getType().getQualifiedName() = "System.ThreadStaticAttribute" and + not this.getAnAttribute().getType().hasQualifiedName("System", "ThreadStaticAttribute") and this.getType() instanceof UsesICryptoTransform } } diff --git a/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql b/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql index 01faeb6ba75..85a7d7ff53a 100644 --- a/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql +++ b/csharp/ql/src/Security Features/CWE-020/UntrustedDataToExternalAPI.ql @@ -10,11 +10,16 @@ */ import csharp +import semmle.code.csharp.commons.QualifiedName import semmle.code.csharp.security.dataflow.ExternalAPIsQuery import DataFlow::PathGraph -from UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from + UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, + string qualifier, string name +where + config.hasFlowPath(source, sink) and + sink.getNode().(ExternalApiDataNode).hasQualifiedName(qualifier, name) select sink, source, sink, - "Call to " + sink.getNode().(ExternalApiDataNode).getCallableDescription() + - " with untrusted data from $@.", source, source.toString() + "Call to " + getQualifiedName(qualifier, name) + " with untrusted data from $@.", source, + source.toString() diff --git a/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql b/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql index 038dc267d14..c537a85c1f1 100644 --- a/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql +++ b/csharp/ql/src/Security Features/CWE-091/XMLInjection.ql @@ -27,7 +27,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { exists(MethodCall mc | mc.getTarget().hasName("WriteRaw") and - mc.getTarget().getDeclaringType().getABaseType*().hasQualifiedName("System.Xml.XmlWriter") + mc.getTarget().getDeclaringType().getABaseType*().hasQualifiedName("System.Xml", "XmlWriter") | mc.getArgument(0) = sink.asExpr() ) @@ -39,7 +39,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { mc.getTarget() .getDeclaringType() .getABaseType*() - .hasQualifiedName("System.Security.SecurityElement") + .hasQualifiedName("System.Security", "SecurityElement") | mc = node.asExpr() ) diff --git a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql index 3ca894db15a..c0990112188 100644 --- a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.ql @@ -3,7 +3,7 @@ * @description Loading a .NET assembly based on a path constructed from user-controlled sources * may allow a malicious user to load code which modifies the program in unintended * ways. - * @kind problem + * @kind path-problem * @id cs/assembly-path-injection * @problem.severity error * @security-severity 8.2 @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Remote import semmle.code.csharp.commons.Util +import DataFlow::PathGraph /** * A taint-tracking configuration for untrusted user input used to load a DLL. @@ -33,7 +34,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { mc.getTarget() .getDeclaringType() .getABaseType*() - .hasQualifiedName("System.Reflection.Assembly") and + .hasQualifiedName("System.Reflection", "Assembly") and mc.getArgument(arg) = sink.asExpr() | name = "LoadFrom" and arg = 0 and mc.getNumberOfArguments() = [1 .. 2] @@ -47,6 +48,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } } -from TaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select sink, "This assembly path depends on a $@.", source, "user-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This assembly path depends on a $@.", source, + "user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql index 8f30847cde0..8e516f44d4a 100644 --- a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql +++ b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql @@ -1,7 +1,7 @@ /** * @name Hard-coded encryption key * @description The .Key property or rgbKey parameter of a SymmetricAlgorithm should never be a hard-coded value. - * @kind problem + * @kind path-problem * @id cs/hardcoded-key * @problem.severity error * @security-severity 8.1 @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.security.cryptography.EncryptionKeyDataFlowQuery +import DataFlow::PathGraph /** * The creation of a literal byte array. @@ -36,7 +37,13 @@ class StringLiteralSource extends KeySource { StringLiteralSource() { this.asExpr() instanceof StringLiteral } } -from SymmetricKeyTaintTrackingConfiguration keyFlow, KeySource src, SymmetricEncryptionKeySink sink -where keyFlow.hasFlow(src, sink) -select sink, "This hard-coded $@ is used in symmetric algorithm in " + sink.getDescription(), src, +from + SymmetricKeyTaintTrackingConfiguration keyFlow, DataFlow::PathNode source, + DataFlow::PathNode sink, KeySource srcNode, SymmetricEncryptionKeySink sinkNode +where + keyFlow.hasFlowPath(source, sink) and + source.getNode() = srcNode and + sink.getNode() = sinkNode +select sink.getNode(), source, sink, + "This hard-coded $@ is used in symmetric algorithm in " + sinkNode.getDescription(), srcNode, "symmetric key" diff --git a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql index 4f7e04f1175..fefd27727ec 100644 --- a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql +++ b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql @@ -21,7 +21,7 @@ class AddCertToRootStoreConfig extends DataFlow::Configuration { exists(ObjectCreation oc | oc = source.asExpr() | oc.getType() .(RefType) - .hasQualifiedName("System.Security.Cryptography.X509Certificates.X509Store") and + .hasQualifiedName("System.Security.Cryptography.X509Certificates", "X509Store") and oc.getArgument(0).(Access).getTarget().hasName("Root") ) } @@ -30,9 +30,10 @@ class AddCertToRootStoreConfig extends DataFlow::Configuration { exists(MethodCall mc | ( mc.getTarget() - .hasQualifiedName("System.Security.Cryptography.X509Certificates.X509Store", "Add") or + .hasQualifiedName("System.Security.Cryptography.X509Certificates", "X509Store", "Add") or mc.getTarget() - .hasQualifiedName("System.Security.Cryptography.X509Certificates.X509Store", "AddRange") + .hasQualifiedName("System.Security.Cryptography.X509Certificates", "X509Store", + "AddRange") ) and sink.asExpr() = mc.getQualifier() ) diff --git a/csharp/ql/src/Security Features/CWE-384/AbandonSession.ql b/csharp/ql/src/Security Features/CWE-384/AbandonSession.ql index ffdb7220f01..e158ac6b366 100644 --- a/csharp/ql/src/Security Features/CWE-384/AbandonSession.ql +++ b/csharp/ql/src/Security Features/CWE-384/AbandonSession.ql @@ -30,7 +30,7 @@ predicate loginMethod(Method m, ControlFlow::SuccessorType flowFrom) { /** The `System.Web.SessionState.HttpSessionState` class. */ class SystemWebSessionStateHttpSessionStateClass extends Class { SystemWebSessionStateHttpSessionStateClass() { - this.hasQualifiedName("System.Web.SessionState.HttpSessionState") + this.hasQualifiedName("System.Web.SessionState", "HttpSessionState") } /** Gets the `Abandon` method. */ diff --git a/csharp/ql/src/Stubs/Stubs.qll b/csharp/ql/src/Stubs/Stubs.qll index 1e562eb3aa7..e4787a9b5ce 100644 --- a/csharp/ql/src/Stubs/Stubs.qll +++ b/csharp/ql/src/Stubs/Stubs.qll @@ -12,6 +12,7 @@ */ import csharp +private import semmle.code.csharp.commons.QualifiedName private import semmle.code.csharp.frameworks.System private import semmle.code.dotnet.DotNet as DotNet // added to handle VoidType as a ValueOrRefType @@ -114,15 +115,18 @@ abstract private class GeneratedType extends Type, GeneratedElement { } private string stubAttributes() { - if this.(ValueOrRefType).getAnAttribute().getType().getQualifiedName() = "System.FlagsAttribute" + if this.(ValueOrRefType).getAnAttribute().getType().hasQualifiedName("System", "FlagsAttribute") then result = "[System.Flags]\n" else result = "" } private string stubComment() { - result = - "// Generated from `" + this.getQualifiedName() + "` in `" + - concat(this.getALocation().toString(), "; ") + "`\n" + exists(string qualifier, string name | + this.hasQualifiedName(qualifier, name) and + result = + "// Generated from `" + getQualifiedName(qualifier, name) + "` in `" + + concat(this.getALocation().toString(), "; ") + "`\n" + ) } /** Gets the entire C# stub code for this type. */ @@ -154,7 +158,7 @@ abstract private class GeneratedType extends Type, GeneratedElement { private ValueOrRefType getAnInterestingBaseType() { result = this.(ValueOrRefType).getABaseType() and not result instanceof ObjectType and - not result.getQualifiedName() = "System.ValueType" and + not result.hasQualifiedName("System", "ValueType") and (not result instanceof Interface or result.(Interface).isEffectivelyPublic()) } @@ -461,7 +465,7 @@ private string stubQualifiedNamePrefix(ValueOrRefType t) { then result = "" else if t.getParent() instanceof Namespace - then result = t.getDeclaringNamespace().getQualifiedName() + "." + then result = t.getDeclaringNamespace().getFullName() + "." else result = stubClassName(t.getDeclaringType()) + "." } diff --git a/csharp/ql/src/Telemetry/ExternalApi.qll b/csharp/ql/src/Telemetry/ExternalApi.qll index d4cc0ae43cc..d1464c4ef56 100644 --- a/csharp/ql/src/Telemetry/ExternalApi.qll +++ b/csharp/ql/src/Telemetry/ExternalApi.qll @@ -17,22 +17,34 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote class TestLibrary extends RefType { TestLibrary() { this.getNamespace() - .getQualifiedName() + .getFullName() .matches([ "NUnit.Framework%", "Xunit%", "Microsoft.VisualStudio.TestTools.UnitTesting%", "Moq%" ]) } } +/** Holds if the given callable is not worth supporting. */ +private predicate isUninteresting(DotNet::Callable c) { + c.getDeclaringType() instanceof TestLibrary or + c.(Constructor).isParameterless() +} + /** * An external API from either the C# Standard Library or a 3rd party library. */ class ExternalApi extends DotNet::Callable { - ExternalApi() { this.isUnboundDeclaration() and this.fromLibrary() } + ExternalApi() { + this.isUnboundDeclaration() and + this.fromLibrary() and + this.(Modifiable).isEffectivelyPublic() and + not isUninteresting(this) + } /** * Gets the unbound type, name and parameter types of this API. */ + bindingset[this] private string getSignature() { result = this.getDeclaringType().getUnboundDeclaration() + "." + this.getName() + "(" + @@ -42,41 +54,33 @@ class ExternalApi extends DotNet::Callable { /** * Gets the namespace of this API. */ - private string getNamespace() { this.getDeclaringType().hasQualifiedName(result, _) } + bindingset[this] + string getNamespace() { this.getDeclaringType().hasQualifiedName(result, _) } /** - * Gets the assembly file name containing this API. + * Gets the namespace and signature of this API. */ - private string getAssembly() { result = this.getFile().getBaseName() } - - /** - * Gets the assembly file name and namespace of this API. - */ - string getInfoPrefix() { result = this.getAssembly() + "#" + this.getNamespace() } - - /** - * Gets the assembly file name, namespace and signature of this API. - */ - string getInfo() { result = this.getInfoPrefix() + "#" + this.getSignature() } - - /** Gets a call to this API callable. */ - DispatchCall getACall() { - this = result.getADynamicTarget().getUnboundDeclaration() - or - this = result.getAStaticTarget().getUnboundDeclaration() - } + bindingset[this] + string getApiName() { result = this.getNamespace() + "#" + this.getSignature() } /** Gets a node that is an input to a call to this API. */ private ArgumentNode getAnInput() { - result.getCall().(DataFlowDispatch::NonDelegateDataFlowCall).getDispatchCall() = this.getACall() + result + .getCall() + .(DataFlowDispatch::NonDelegateDataFlowCall) + .getATarget(_) + .getUnboundDeclaration() = this } /** Gets a node that is an output from a call to this API. */ private DataFlow::Node getAnOutput() { - exists(DataFlowDispatch::NonDelegateDataFlowCall call, DataFlowImplCommon::ReturnKindExt ret | - result = ret.getAnOutNode(call) + exists( + Call c, DataFlowDispatch::NonDelegateDataFlowCall dc, DataFlowImplCommon::ReturnKindExt ret | - this.getACall() = call.getDispatchCall() + dc.getDispatchCall().getCall() = c and + c.getTarget().getUnboundDeclaration() = this + | + result = ret.getAnOutNode(dc) ) } @@ -87,17 +91,6 @@ class ExternalApi extends DotNet::Callable { defaultAdditionalTaintStep(this.getAnInput(), _) } - /** Holds if this API is a constructor without parameters. */ - private predicate isParameterlessConstructor() { - this instanceof Constructor and this.getNumberOfParameters() = 0 - } - - /** Holds if this API is part of a common testing library or framework. */ - private predicate isTestLibrary() { this.getDeclaringType() instanceof TestLibrary } - - /** Holds if this API is not worth supporting. */ - predicate isUninteresting() { this.isTestLibrary() or this.isParameterlessConstructor() } - /** Holds if this API is a known source. */ predicate isSource() { this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) @@ -125,30 +118,30 @@ signature predicate relevantApi(ExternalApi api); * for restricting the number or returned results based on a certain limit. */ module Results { - private int getUsages(string apiInfo) { + private int getUsages(string apiName) { result = - strictcount(DispatchCall c, ExternalApi api | - c = api.getACall() and - apiInfo = api.getInfo() and + strictcount(Call c, ExternalApi api | + c.getTarget().getUnboundDeclaration() = api and + apiName = api.getApiName() and getRelevantUsages(api) ) } - private int getOrder(string apiInfo) { - apiInfo = - rank[result](string info, int usages | - usages = getUsages(info) + private int getOrder(string apiName) { + apiName = + rank[result](string name, int usages | + usages = getUsages(name) | - info order by usages desc, info + name order by usages desc, name ) } /** - * Holds if there exists an API with `apiInfo` that is being used `usages` times + * Holds if there exists an API with `apiName` that is being used `usages` times * and if it is in the top results (guarded by resultLimit). */ - predicate restrict(string apiInfo, int usages) { - usages = getUsages(apiInfo) and - getOrder(apiInfo) <= resultLimit() + predicate restrict(string apiName, int usages) { + usages = getUsages(apiName) and + getOrder(apiName) <= resultLimit() } } diff --git a/csharp/ql/src/Telemetry/ExternalLibraryUsage.ql b/csharp/ql/src/Telemetry/ExternalLibraryUsage.ql index dfc1a8e062c..f28fa1c76fb 100644 --- a/csharp/ql/src/Telemetry/ExternalLibraryUsage.ql +++ b/csharp/ql/src/Telemetry/ExternalLibraryUsage.ql @@ -1,6 +1,6 @@ /** * @name External libraries - * @description A list of external libraries used in the code + * @description A list of external libraries used in the code given by their namespace. * @kind metric * @tags summary telemetry * @id csharp/telemetry/external-libs @@ -10,23 +10,22 @@ private import csharp private import semmle.code.csharp.dispatch.Dispatch private import ExternalApi -private predicate getRelevantUsages(string info, int usages) { +private predicate getRelevantUsages(string namespace, int usages) { usages = - strictcount(DispatchCall c, ExternalApi api | - c = api.getACall() and - api.getInfoPrefix() = info and - not api.isUninteresting() + strictcount(Call c, ExternalApi api | + c.getTarget().getUnboundDeclaration() = api and + api.getNamespace() = namespace ) } -private int getOrder(string info) { - info = +private int getOrder(string namespace) { + namespace = rank[result](string i, int usages | getRelevantUsages(i, usages) | i order by usages desc, i) } -from ExternalApi api, string info, int usages +from ExternalApi api, string namespace, int usages where - info = api.getInfoPrefix() and - getRelevantUsages(info, usages) and - getOrder(info) <= resultLimit() -select info, usages order by usages desc + namespace = api.getNamespace() and + getRelevantUsages(namespace, usages) and + getOrder(namespace) <= resultLimit() +select namespace, usages order by usages desc diff --git a/csharp/ql/src/Telemetry/SupportedExternalApis.ql b/csharp/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..1aa08bbd3aa --- /dev/null +++ b/csharp/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,21 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes APIs exposed by test libraries. + * @kind metric + * @tags summary telemetry + * @id csharp/telemetry/supported-external-api + */ + +private import csharp +private import semmle.code.csharp.dispatch.Dispatch +private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +private import ExternalApi + +private predicate relevant(ExternalApi api) { + api.isSupported() or + api instanceof FlowSummaryImpl::Public::NeutralCallable +} + +from string info, int usages +where Results::restrict(info, usages) +select info, usages order by usages desc diff --git a/csharp/ql/src/Telemetry/SupportedExternalSinks.ql b/csharp/ql/src/Telemetry/SupportedExternalSinks.ql index 4eb42c4628f..542834bc057 100644 --- a/csharp/ql/src/Telemetry/SupportedExternalSinks.ql +++ b/csharp/ql/src/Telemetry/SupportedExternalSinks.ql @@ -10,10 +10,7 @@ private import csharp private import semmle.code.csharp.dispatch.Dispatch private import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.isSink() -} +private predicate relevant(ExternalApi api) { api.isSink() } from string info, int usages where Results::restrict(info, usages) diff --git a/csharp/ql/src/Telemetry/SupportedExternalSources.ql b/csharp/ql/src/Telemetry/SupportedExternalSources.ql index 0d0b38a4754..d2293b2d3cf 100644 --- a/csharp/ql/src/Telemetry/SupportedExternalSources.ql +++ b/csharp/ql/src/Telemetry/SupportedExternalSources.ql @@ -10,10 +10,7 @@ private import csharp private import semmle.code.csharp.dispatch.Dispatch private import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.isSource() -} +private predicate relevant(ExternalApi api) { api.isSource() } from string info, int usages where Results::restrict(info, usages) diff --git a/csharp/ql/src/Telemetry/SupportedExternalTaint.ql b/csharp/ql/src/Telemetry/SupportedExternalTaint.ql index 3eccf73b58b..a76467f0142 100644 --- a/csharp/ql/src/Telemetry/SupportedExternalTaint.ql +++ b/csharp/ql/src/Telemetry/SupportedExternalTaint.ql @@ -10,10 +10,7 @@ private import csharp private import semmle.code.csharp.dispatch.Dispatch private import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.hasSummary() -} +private predicate relevant(ExternalApi api) { api.hasSummary() } from string info, int usages where Results::restrict(info, usages) diff --git a/csharp/ql/src/Telemetry/UnsupportedExternalAPIs.ql b/csharp/ql/src/Telemetry/UnsupportedExternalAPIs.ql index 618f26e6636..01d9e280133 100644 --- a/csharp/ql/src/Telemetry/UnsupportedExternalAPIs.ql +++ b/csharp/ql/src/Telemetry/UnsupportedExternalAPIs.ql @@ -12,9 +12,8 @@ private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSumma private import ExternalApi private predicate relevant(ExternalApi api) { - not api.isUninteresting() and not api.isSupported() and - not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable + not api instanceof FlowSummaryImpl::Public::NeutralCallable } from string info, int usages diff --git a/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..34bf2ef8409 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `csharp/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. diff --git a/csharp/ql/src/change-notes/2022-12-05-owin-uri-fix.md b/csharp/ql/src/change-notes/2022-12-05-owin-uri-fix.md new file mode 100644 index 00000000000..e92df82a41c --- /dev/null +++ b/csharp/ql/src/change-notes/2022-12-05-owin-uri-fix.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixes a bug where the Owin.qll framework library will look for "URI" instead of "Uri" in the OwinRequest class. diff --git a/csharp/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md b/csharp/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md new file mode 100644 index 00000000000..39532da22c8 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The extensible predicates for Models as Data have been renamed (the `ext` prefix has been removed). As an example `extSummaryModel` has been renamed to `summaryModel`. \ No newline at end of file diff --git a/csharp/ql/src/change-notes/released/0.4.4.md b/csharp/ql/src/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..33e1c91255d --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.4.4.md @@ -0,0 +1,3 @@ +## 0.4.4 + +No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.4.5.md b/csharp/ql/src/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.4.6.md b/csharp/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md b/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md new file mode 100644 index 00000000000..9e2d667d2eb --- /dev/null +++ b/csharp/ql/src/change-notes/released/2022-11-07-constant-expression.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `Constant Condition` query was extended to catch cases when `String.IsNullOrEmpty` returns a constant value. \ No newline at end of file diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll b/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll index e9da88e0d27..5f04d766827 100644 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll +++ b/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll @@ -51,9 +51,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } /** A source of remote user input. */ -class RemoteSource extends Source { - RemoteSource() { this instanceof RemoteFlowSource } -} +class RemoteSource extends Source instanceof RemoteFlowSource { } /** * A path argument to a `WebClient` method call that has an address argument. diff --git a/csharp/ql/src/experimental/CWE-918/RequestForgery.qll b/csharp/ql/src/experimental/CWE-918/RequestForgery.qll index fd08734fb5f..868e1e29a13 100644 --- a/csharp/ql/src/experimental/CWE-918/RequestForgery.qll +++ b/csharp/ql/src/experimental/CWE-918/RequestForgery.qll @@ -58,9 +58,7 @@ module RequestForgery { * A remote data flow source taken as a source * for Server Side Request Forgery(SSRF) Vulnerabilities. */ - private class RemoteFlowSourceAsSource extends Source { - RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource } - } + private class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { } /** * An url argument to a `HttpRequestMessage` constructor call @@ -68,7 +66,7 @@ module RequestForgery { */ private class SystemWebHttpRequestMessageSink extends Sink { SystemWebHttpRequestMessageSink() { - exists(Class c | c.hasQualifiedName("System.Net.Http.HttpRequestMessage") | + exists(Class c | c.hasQualifiedName("System.Net.Http", "HttpRequestMessage") | c.getAConstructor().getACall().getArgument(1) = this.asExpr() ) } @@ -81,7 +79,7 @@ module RequestForgery { private class SystemNetWebRequestCreateSink extends Sink { SystemNetWebRequestCreateSink() { exists(Method m | - m.getDeclaringType().hasQualifiedName("System.Net.WebRequest") and m.hasName("Create") + m.getDeclaringType().hasQualifiedName("System.Net", "WebRequest") and m.hasName("Create") | m.getACall().getArgument(0) = this.asExpr() ) @@ -95,7 +93,7 @@ module RequestForgery { private class SystemNetHttpClientSink extends Sink { SystemNetHttpClientSink() { exists(Method m | - m.getDeclaringType().hasQualifiedName("System.Net.Http.HttpClient") and + m.getDeclaringType().hasQualifiedName("System.Net.Http", "HttpClient") and m.hasName([ "DeleteAsync", "GetAsync", "GetByteArrayAsync", "GetStreamAsync", "GetStringAsync", "PatchAsync", "PostAsync", "PutAsync" @@ -112,10 +110,13 @@ module RequestForgery { */ private class SystemNetClientBaseAddressSink extends Sink { SystemNetClientBaseAddressSink() { - exists(Property p | + exists(Property p, Type t | p.hasName("BaseAddress") and - p.getDeclaringType() - .hasQualifiedName(["System.Net.WebClient", "System.Net.Http.HttpClient"]) + t = p.getDeclaringType() and + ( + t.hasQualifiedName("System.Net", "WebClient") or + t.hasQualifiedName("System.Net.Http", "HttpClient") + ) | p.getAnAssignedValue() = this.asExpr() ) @@ -128,7 +129,7 @@ module RequestForgery { * This guard considers all checks as valid. */ private predicate baseUriGuard(Guard g, Expr e, AbstractValue v) { - g.(MethodCall).getTarget().hasQualifiedName("System.Uri", "IsBaseOf") and + g.(MethodCall).getTarget().hasQualifiedName("System", "Uri", "IsBaseOf") and // we consider any checks against the tainted value to sainitize the taint. // This implies any check such as shown below block the taint flow. // Uri url = new Uri("whitelist.com") @@ -147,7 +148,7 @@ module RequestForgery { * This guard considers all checks as valid. */ private predicate stringStartsWithGuard(Guard g, Expr e, AbstractValue v) { - g.(MethodCall).getTarget().hasQualifiedName("System.String", "StartsWith") and + g.(MethodCall).getTarget().hasQualifiedName("System", "String", "StartsWith") and // Any check such as the ones shown below // "https://myurl.com/".startsWith(`taint`) // `taint`.startsWith("https://myurl.com/") @@ -168,7 +169,7 @@ module RequestForgery { private predicate pathCombineStep(DataFlow::Node prev, DataFlow::Node succ) { exists(MethodCall combineCall | - combineCall.getTarget().hasQualifiedName("System.IO.Path", "Combine") and + combineCall.getTarget().hasQualifiedName("System.IO", "Path", "Combine") and combineCall.getArgument(0) = prev.asExpr() and combineCall = succ.asExpr() ) @@ -176,7 +177,7 @@ module RequestForgery { private predicate uriCreationStep(DataFlow::Node prev, DataFlow::Node succ) { exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasQualifiedName("System.Uri") and + oc.getTarget().getDeclaringType().hasQualifiedName("System", "Uri") and oc.getArgument(0) = prev.asExpr() and oc = succ.asExpr() ) @@ -217,7 +218,7 @@ module RequestForgery { private predicate formatConvertStep(DataFlow::Node prev, DataFlow::Node succ) { exists(Method m | - m.hasQualifiedName("System.Convert", + m.hasQualifiedName("System", "Convert", ["FromBase64String", "FromHexString", "FromBase64CharArray"]) and m.getParameter(0) = prev.asParameter() and succ.asExpr() = m.getACall() diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index eb1cb673ed2..be503fe31d1 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -18,7 +18,7 @@ import csharp */ predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { exists(Parameter p | p.hasName("version") | - c.hasQualifiedName("Azure.Storage.ClientSideEncryptionOptions") and + c.hasQualifiedName("Azure.Storage", "ClientSideEncryptionOptions") and oc.getTarget() = c.getAConstructor() and e = oc.getArgumentForParameter(p) ) @@ -28,7 +28,7 @@ predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, * Holds if `oc` is an object creation of the outdated type `c` = `Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy` */ predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, Class c) { - c.hasQualifiedName("Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy") and + c.hasQualifiedName("Microsoft.Azure.Storage.Blob", "BlobEncryptionPolicy") and oc.getTarget() = c.getAConstructor() } @@ -62,7 +62,7 @@ predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr version */ predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) { exists(EnumConstant ec | - ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and + ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion", "V2_0") and ec.getAnAccess() = e ) } diff --git a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql b/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql index edcbf425497..a833ac79898 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql @@ -96,10 +96,10 @@ predicate hasAnotherHashCall(MethodCall mc) { predicate hasFurtherProcessing(MethodCall mc) { mc.getTarget().fromLibrary() and ( - mc.getTarget().hasQualifiedName("System.Array", "Copy") or // Array.Copy(passwordHash, 0, password.Length), 0, key, 0, keyLen); - mc.getTarget().hasQualifiedName("System.String", "Concat") or // string.Concat(passwordHash, saltkey) - mc.getTarget().hasQualifiedName("System.Buffer", "BlockCopy") or // Buffer.BlockCopy(passwordHash, 0, allBytes, 0, 20) - mc.getTarget().hasQualifiedName("System.String", "Format") // String.Format("{0}:{1}:{2}", username, salt, password) + mc.getTarget().hasQualifiedName("System", "Array", "Copy") or // Array.Copy(passwordHash, 0, password.Length), 0, key, 0, keyLen); + mc.getTarget().hasQualifiedName("System", "String", "Concat") or // string.Concat(passwordHash, saltkey) + mc.getTarget().hasQualifiedName("System", "Buffer", "BlockCopy") or // Buffer.BlockCopy(passwordHash, 0, allBytes, 0, 20) + mc.getTarget().hasQualifiedName("System", "String", "Format") // String.Format("{0}:{1}:{2}", username, salt, password) ) } @@ -150,7 +150,7 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration { override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { exists(MethodCall mc | mc.getTarget() - .hasQualifiedName("Windows.Security.Cryptography.CryptographicBuffer", + .hasQualifiedName("Windows.Security.Cryptography", "CryptographicBuffer", "ConvertStringToBinary") and mc.getArgument(0) = node1.asExpr() and mc = node2.asExpr() diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index bf9df3e5184..636400ceb33 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -7,7 +7,7 @@ import DataFlow class TokenValidationParametersPropertySensitiveValidation extends Property { TokenValidationParametersPropertySensitiveValidation() { exists(Class c | - c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") + c.hasQualifiedName("Microsoft.IdentityModel.Tokens", "TokenValidationParameters") | c.getAProperty() = this and this.getName() in [ @@ -52,8 +52,10 @@ predicate isAssemblyOlderVersion(string assemblyName, string ver) { */ class JsonWebTokenHandlerValidateTokenMethod extends Method { JsonWebTokenHandlerValidateTokenMethod() { - this.hasQualifiedName("Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken") or - this.hasQualifiedName("Microsoft.AzureAD.DeviceIdentification.Common.Tokens.JwtValidator.ValidateEncryptedToken") + this.hasQualifiedName("Microsoft.IdentityModel.JsonWebTokens", "JsonWebTokenHandler", + "ValidateToken") or + this.hasQualifiedName("Microsoft.AzureAD.DeviceIdentification.Common.Tokens", "JwtValidator", + "ValidateEncryptedToken") } } @@ -99,7 +101,7 @@ private class FlowsToTokenValidationResultIsValidCall extends DataFlow::Configur class TokenValidationParametersProperty extends Property { TokenValidationParametersProperty() { exists(Class c | - c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") + c.hasQualifiedName("Microsoft.IdentityModel.Tokens", "TokenValidationParameters") | c.getAProperty() = this and this.getName() in [ @@ -158,7 +160,7 @@ class CallableAlwaysReturnsTrue extends Callable { */ predicate callableOnlyThrowsArgumentNullException(Callable c) { forall(ThrowElement thre | c = thre.getEnclosingCallable() | - thre.getThrownExceptionType().hasQualifiedName("System.ArgumentNullException") + thre.getThrownExceptionType().hasQualifiedName("System", "ArgumentNullException") ) } diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 753dfb82999..2ee7c7edb1f 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -14,9 +14,12 @@ import csharp import DataFlow import JsonWebTokenHandlerLib +import semmle.code.csharp.commons.QualifiedName -from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e -where e = p.getAnAssignedValue() +from + TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e, string qualifier, + string name +where e = p.getAnAssignedValue() and p.hasQualifiedName(qualifier, name) select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\".", - p, p.getQualifiedName().toString() + p, getQualifiedName(qualifier, name) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql index 9c2a5d3983f..84c846c3a91 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -12,13 +12,15 @@ import csharp import JsonWebTokenHandlerLib +import semmle.code.csharp.commons.QualifiedName from FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation config, DataFlow::Node source, DataFlow::Node sink, - TokenValidationParametersPropertySensitiveValidation pw + TokenValidationParametersPropertySensitiveValidation pw, string qualifier, string name where config.hasFlow(source, sink) and - sink.asExpr() = pw.getAnAssignedValue() + sink.asExpr() = pw.getAnAssignedValue() and + pw.hasQualifiedName(qualifier, name) select sink, "The security sensitive property $@ is being disabled by the following value: $@.", pw, - pw.getQualifiedName().toString(), source, "false" + getQualifiedName(qualifier, name), source, "false" diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll b/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll index a6230b0ff59..79aa9e30e5e 100644 --- a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll +++ b/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll @@ -16,8 +16,8 @@ abstract class DataSetOrTableRelatedClass extends Class { } */ class DataSetOrTable extends DataSetOrTableRelatedClass { DataSetOrTable() { - this.getABaseType*().getQualifiedName() = "System.Data.DataTable" or - this.getABaseType*().getQualifiedName() = "System.Data.DataSet" + this.getABaseType*().hasQualifiedName("System.Data", "DataTable") or + this.getABaseType*().hasQualifiedName("System.Data", "DataSet") } } @@ -41,18 +41,18 @@ class ClassWithDataSetOrTableMember extends DataSetOrTableRelatedClass { class SerializableClass extends Class { SerializableClass() { ( - this.getABaseType*().getQualifiedName() = "System.Xml.Serialization.XmlSerializer" or - this.getABaseType*().getQualifiedName() = "System.Runtime.Serialization.ISerializable" or - this.getABaseType*().getQualifiedName() = "System.Runtime.Serialization.XmlObjectSerializer" or - this.getABaseType*().getQualifiedName() = - "System.Runtime.Serialization.ISerializationSurrogateProvider" or - this.getABaseType*().getQualifiedName() = - "System.Runtime.Serialization.XmlSerializableServices" or - this.getABaseType*().getQualifiedName() = "System.Xml.Serialization.IXmlSerializable" + this.getABaseType*() + .hasQualifiedName("System.Xml.Serialization", ["XmlSerializer", "IXmlSerializable"]) or + this.getABaseType*() + .hasQualifiedName("System.Runtime.Serialization", + [ + "ISerializable", "XmlObjectSerializer", "ISerializationSurrogateProvider", + "XmlSerializableServices" + ]) ) or exists(Attribute a | a = this.getAnAttribute() | - a.getType().getQualifiedName() = "System.SerializableAttribute" + a.getType().hasQualifiedName("System", "SerializableAttribute") ) } } @@ -77,13 +77,7 @@ class UnsafeXmlSerializerImplementation extends SerializableClass { */ class UnsafeXmlReadMethod extends Method { UnsafeXmlReadMethod() { - this.getQualifiedName() = "System.Data.DataTable.ReadXml" - or - this.getQualifiedName() = "System.Data.DataTable.ReadXmlSchema" - or - this.getQualifiedName() = "System.Data.DataSet.ReadXml" - or - this.getQualifiedName() = "System.Data.DataSet.ReadXmlSchema" + this.hasQualifiedName("System.Data", ["DataTable", "DataSet"], ["ReadXml", "ReadXmlSchema"]) or this.getName().matches("ReadXml%") and exists(Class c | c.getAMethod() = this | diff --git a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql b/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql index f3a83b67926..5907e4be311 100644 --- a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql +++ b/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql @@ -14,7 +14,9 @@ import DataSetSerialization predicate xmlSerializerConstructorArgument(Expr e) { exists(ObjectCreation oc, Constructor c | e = oc.getArgument(0) | c = oc.getTarget() and - c.getDeclaringType().getABaseType*().hasQualifiedName("System.Xml.Serialization.XmlSerializer") + c.getDeclaringType() + .getABaseType*() + .hasQualifiedName("System.Xml.Serialization", "XmlSerializer") ) } diff --git a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql b/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql index 9de38f673ab..9ccbd675486 100644 --- a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql +++ b/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql @@ -45,10 +45,8 @@ query predicate edges(DataFlow::PathNode a, DataFlow::PathNode b) { */ class GetLastWriteTimeMethod extends Method { GetLastWriteTimeMethod() { - this.getQualifiedName() in [ - "System.IO.File.GetLastWriteTime", "System.IO.File.GetFileCreationTime", - "System.IO.File.GetCreationTimeUtc", "System.IO.File.GetLastAccessTimeUtc" - ] + this.hasQualifiedName("System.IO.File", + ["GetLastWriteTime", "GetFileCreationTime", "GetCreationTimeUtc", "GetLastAccessTimeUtc"]) } } @@ -56,7 +54,7 @@ class GetLastWriteTimeMethod extends Method { * Abstracts `System.DateTime` structure */ class DateTimeStruct extends Struct { - DateTimeStruct() { this.getQualifiedName() = "System.DateTime" } + DateTimeStruct() { this.hasQualifiedName("System", "DateTime") } /** * holds if the Callable is used for DateTime arithmetic operations diff --git a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql index 5bb8a1dc6e9..6f5acf29f1d 100644 --- a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql +++ b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql @@ -44,7 +44,7 @@ predicate isGetHash(Expr arg) { } predicate isSuspiciousPropertyName(PropertyRead pr) { - pr.getTarget().getQualifiedName() = "System.Diagnostics.Process.ProcessName" + pr.getTarget().hasQualifiedName("System.Diagnostics", "Process", "ProcessName") } from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll index e061a1371b2..bb1ab29e51c 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Lock.qll @@ -128,7 +128,7 @@ private class TranslatedMonitorExit extends TranslatedCompilerGeneratedCall, override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and exists(Callable exit | - exit.getQualifiedName() = "System.Threading.Monitor.Exit" and + exit.hasQualifiedName("System.Threading.Monitor", "Exit") and result = exit ) } @@ -160,7 +160,7 @@ private class TranslatedMonitorEnter extends TranslatedCompilerGeneratedCall, override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and exists(Callable dispose | - dispose.getQualifiedName() = "System.Threading.Monitor.Enter" and + dispose.hasQualifiedName("System.Threading.Monitor", "Enter") and result = dispose ) } diff --git a/csharp/ql/src/meta/frameworks/UnsupportedExternalAPIs.ql b/csharp/ql/src/meta/frameworks/UnsupportedExternalAPIs.ql index b7e2d1241a0..1c342affc5e 100644 --- a/csharp/ql/src/meta/frameworks/UnsupportedExternalAPIs.ql +++ b/csharp/ql/src/meta/frameworks/UnsupportedExternalAPIs.ql @@ -13,10 +13,9 @@ private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import Telemetry.ExternalApi -from DispatchCall c, ExternalApi api +from Call c, ExternalApi api where - c = api.getACall() and - not api.isUninteresting() and + c.getTarget().getUnboundDeclaration() = api and not api.isSupported() and - not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable + not api instanceof FlowSummaryImpl::Public::NeutralCallable select c, "Call to unsupported external API $@.", api, api.toString() diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 7f537bcae49..926a272097e 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.4-dev +version: 0.5.0-dev groups: - csharp - queries diff --git a/csharp/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql b/csharp/ql/src/utils/model-generator/CaptureNeutralModels.ql similarity index 66% rename from csharp/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql rename to csharp/ql/src/utils/model-generator/CaptureNeutralModels.ql index 9188b54ef40..9cf2b81ba7c 100644 --- a/csharp/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql +++ b/csharp/ql/src/utils/model-generator/CaptureNeutralModels.ql @@ -1,8 +1,8 @@ /** - * @name Capture negative summary models. - * @description Finds negative summary models to be used by other queries. + * @name Capture neutral models. + * @description Finds neutral models to be used by other queries. * @kind diagnostic - * @id cs/utils/model-generator/negative-summary-models + * @id cs/utils/model-generator/neutral-models * @tags model-generator */ diff --git a/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql b/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql index 7cd23988321..f15a786f53f 100644 --- a/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql +++ b/csharp/ql/src/utils/model-generator/CaptureTypeBasedSummaryModels.ql @@ -6,7 +6,6 @@ * @tags model-generator */ -import semmle.code.csharp.dataflow.ExternalFlow import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels from TypeBasedFlowTargetApi api, string flow diff --git a/csharp/ql/src/utils/model-generator/GenerateFlowModelExtensions.py b/csharp/ql/src/utils/model-generator/GenerateFlowModelExtensions.py deleted file mode 100755 index 0e93d34c8cf..00000000000 --- a/csharp/ql/src/utils/model-generator/GenerateFlowModelExtensions.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/python3 - -import sys -import os.path -import subprocess - -# Add Model as Data script directory to sys.path. -gitroot = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip() -madpath = os.path.join(gitroot, "misc/scripts/models-as-data/") -sys.path.append(madpath) - -import generate_flow_model_extensions as model - -language = "csharp" -model.Generator.make(language).run() \ No newline at end of file diff --git a/csharp/ql/src/utils/modelconverter/ExtractNeutrals.ql b/csharp/ql/src/utils/modelconverter/ExtractNeutrals.ql new file mode 100644 index 00000000000..5ca6ef9579c --- /dev/null +++ b/csharp/ql/src/utils/modelconverter/ExtractNeutrals.ql @@ -0,0 +1,14 @@ +/** + * @name Extract MaD neutral model rows. + * @description This extracts the Models as data neutral model rows. + * @id csharp/utils/modelconverter/generate-data-extensions-neutral + */ + +import csharp +import semmle.code.csharp.dataflow.ExternalFlow + +from string package, string type, string name, string signature, string provenance +where + neutralModel(package, type, name, signature, provenance) and + provenance != "generated" +select package, type, name, signature, provenance order by package, type, name, signature diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll index f40b028ba6d..893c62191b3 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -58,9 +58,7 @@ private string asSummaryModel(TargetApiSpecific api, string input, string output + "generated" } -string asNegativeSummaryModel(TargetApiSpecific api) { - result = asPartialNegativeModel(api) + "generated" -} +string asNeutralModel(TargetApiSpecific api) { result = asPartialNeutralModel(api) + "generated" } /** * Gets the value summary model for `api` with `input` and `output`. diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 18366b1a5d6..1fc7636ca65 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -35,10 +35,12 @@ private predicate isHigherOrder(CS::Callable api) { */ private predicate isRelevantForModels(CS::Callable api) { [api.(CS::Modifiable), api.(CS::Accessor).getDeclaration()].isEffectivelyPublic() and - api.getDeclaringType().getNamespace().getQualifiedName() != "" and + api.getDeclaringType().getNamespace().getFullName() != "" and not api instanceof CS::ConversionOperator and not api instanceof Util::MainMethod and - not api instanceof CS::Destructor + not api instanceof CS::Destructor and + not api instanceof CS::AnonymousFunctionExpr and + not api.(CS::Constructor).isParameterless() } /** @@ -68,7 +70,7 @@ class TargetApiSpecific extends DotNet::Callable { predicate asPartialModel = DataFlowPrivate::Csv::asPartialModel/1; -predicate asPartialNegativeModel = DataFlowPrivate::Csv::asPartialNegativeModel/1; +predicate asPartialNeutralModel = DataFlowPrivate::Csv::asPartialNeutralModel/1; /** * Holds if `t` is a type that is generally used for bulk data in collection types. diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll index 2f16baec794..1ed6b9a4850 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll @@ -85,10 +85,10 @@ string captureFlow(DataFlowTargetApi api) { } /** - * Gets the negative summary for `api`, if any. - * A negative summary is generated, if there does not exist any positive flow. + * Gets the neutral model for `api`, if any. + * A neutral model is generated, if there does not exist summary model. */ string captureNoFlow(DataFlowTargetApi api) { not exists(captureFlow(api)) and - result = asNegativeSummaryModel(api) + result = asNeutralModel(api) } diff --git a/csharp/ql/test/library-tests/assemblies/assemblies.ql b/csharp/ql/test/library-tests/assemblies/assemblies.ql index 98db2a0f973..70d9c419d5a 100644 --- a/csharp/ql/test/library-tests/assemblies/assemblies.ql +++ b/csharp/ql/test/library-tests/assemblies/assemblies.ql @@ -20,7 +20,7 @@ from Class class1, MissingType class2, MissingType class3, MissingType class4, MissingType class5, MissingType del2, Field a, Method b, Method c, Method d, Method e, Method f, Method g where - class1.hasQualifiedName("Assembly1.Class1") and + class1.hasQualifiedName("Assembly1", "Class1") and class2.hasName("Class2") and class3.hasName("Class3") and class4.hasName("Class4") and @@ -34,7 +34,6 @@ where f.hasName("f") and g.hasName("g") and a.getDeclaringType() = class1 and - a.getDeclaringType() = class1 and b.getDeclaringType() = class1 and c.getDeclaringType() = class1 and not exists(c.getParameter(0).getType().(KnownType)) and diff --git a/csharp/ql/test/library-tests/assemblies/locations.ql b/csharp/ql/test/library-tests/assemblies/locations.ql index df22a55ca3c..0e368fd4792 100644 --- a/csharp/ql/test/library-tests/assemblies/locations.ql +++ b/csharp/ql/test/library-tests/assemblies/locations.ql @@ -2,7 +2,7 @@ import csharp from Element e, Class c, Method m, Parameter p where - c.hasQualifiedName("Locations.Test") and + c.hasQualifiedName("Locations", "Test") and m.getDeclaringType() = c and m.getAParameter() = p and (e = c or e = m or e = p) diff --git a/csharp/ql/test/library-tests/async/Async.ql b/csharp/ql/test/library-tests/async/Async.ql index afb279e8100..9ddd4c24c83 100644 --- a/csharp/ql/test/library-tests/async/Async.ql +++ b/csharp/ql/test/library-tests/async/Async.ql @@ -1,5 +1,5 @@ import csharp from Method m -where m.getDeclaringType().getQualifiedName() = "Semmle.Asynchronous" +where m.getDeclaringType().hasQualifiedName("Semmle", "Asynchronous") select m, m.getAModifier() diff --git a/csharp/ql/test/library-tests/attributes/AttributeElements.ql b/csharp/ql/test/library-tests/attributes/AttributeElements.ql index cbcfae12bda..198fd905b21 100644 --- a/csharp/ql/test/library-tests/attributes/AttributeElements.ql +++ b/csharp/ql/test/library-tests/attributes/AttributeElements.ql @@ -1,7 +1,9 @@ import csharp +import semmle.code.csharp.commons.QualifiedName -from Attributable element, Attribute attribute +from Attributable element, Attribute attribute, string qualifier, string name where attribute = element.getAnAttribute() and - (attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"]) -select element, attribute, attribute.getType().getQualifiedName() + (attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"]) and + attribute.getType().hasQualifiedName(qualifier, name) +select element, attribute, getQualifiedName(qualifier, name) diff --git a/csharp/ql/test/library-tests/cil/consistency/Handles.ql b/csharp/ql/test/library-tests/cil/consistency/Handles.ql index e67e4b29416..d3a71af4209 100644 --- a/csharp/ql/test/library-tests/cil/consistency/Handles.ql +++ b/csharp/ql/test/library-tests/cil/consistency/Handles.ql @@ -1,6 +1,7 @@ import csharp import cil import dotnet +import semmle.code.csharp.commons.QualifiedName class MetadataEntity extends DotNet::NamedElement, @metadata_entity { int getHandle() { metadata_handle(this, _, result) } @@ -11,9 +12,10 @@ class MetadataEntity extends DotNet::NamedElement, @metadata_entity { } query predicate tooManyHandles(string s) { - exists(MetadataEntity e, Assembly a | + exists(MetadataEntity e, Assembly a, string qualifier, string name | strictcount(int handle | metadata_handle(e, a, handle)) > 1 and - s = e.getQualifiedName() + e.hasQualifiedName(qualifier, name) and + s = getQualifiedName(qualifier, name) ) } @@ -21,15 +23,19 @@ private class UniqueMetadataEntity extends MetadataEntity { UniqueMetadataEntity() { // Tuple types such as `(,)` and `ValueTuple`2` share the same handle not this instanceof TupleType and - not this.getQualifiedName().matches("System.ValueTuple%") + not exists(string name | + this.hasQualifiedName("System", name) and + name.matches("System.ValueTuple%") + ) } } query predicate tooManyMatchingHandles(string s) { - exists(UniqueMetadataEntity e, Assembly a, int handle | + exists(UniqueMetadataEntity e, Assembly a, int handle, string qualifier, string name | metadata_handle(e, a, handle) and strictcount(UniqueMetadataEntity e2 | metadata_handle(e2, a, handle)) > 2 and - s = e.getQualifiedName() + e.hasQualifiedName(qualifier, name) and + s = getQualifiedName(qualifier, name) ) } @@ -54,7 +60,7 @@ query predicate csharpLocationViolation(Element e) { query predicate matchingObjectMethods(string s1, string s2) { exists(Callable m1, CIL::Method m2 | - m1.getDeclaringType().getQualifiedName() = "System.Object" and + m1.getDeclaringType().hasQualifiedName("System", "Object") and m1.matchesHandle(m2) and s1 = m1.toStringWithTypes() and s2 = m2.toStringWithTypes() diff --git a/csharp/ql/test/library-tests/cil/dataflow/TrivialProperties.ql b/csharp/ql/test/library-tests/cil/dataflow/TrivialProperties.ql index edca7e6cb4b..577ee105802 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/TrivialProperties.ql +++ b/csharp/ql/test/library-tests/cil/dataflow/TrivialProperties.ql @@ -1,10 +1,15 @@ import csharp +import semmle.code.csharp.commons.QualifiedName -from TrivialProperty prop +from TrivialProperty prop, string namespace, string type, string name where - prop.getDeclaringType().hasQualifiedName("System.Reflection.AssemblyName") - or - prop.getDeclaringType().hasQualifiedName("System.Collections.DictionaryEntry") - or - prop.getDeclaringType().hasQualifiedName("Dataflow.Properties") -select prop.getQualifiedName() + prop.getDeclaringType().hasQualifiedName(namespace, type) and + ( + namespace = "System.Reflection" and type = "AssemblyName" + or + namespace = "System.Collections" and type = "DictionaryEntry" + or + namespace = "Dataflow" and type = "Properties" + ) and + prop.hasQualifiedName(namespace, type, name) +select getQualifiedName(namespace, type, name) diff --git a/csharp/ql/test/library-tests/cil/enums/enums.ql b/csharp/ql/test/library-tests/cil/enums/enums.ql index 280bee49921..096ac2f6d02 100644 --- a/csharp/ql/test/library-tests/cil/enums/enums.ql +++ b/csharp/ql/test/library-tests/cil/enums/enums.ql @@ -1,5 +1,8 @@ import semmle.code.cil.Types +import semmle.code.csharp.commons.QualifiedName -from Enum e -where e.getQualifiedName() != "Interop.Sys.LockType" // doesn't exist on osx -select e.getQualifiedName(), e.getUnderlyingType().toStringWithTypes() +from Enum e, string qualifier, string name +where + e.hasQualifiedName(qualifier, name) and + not (qualifier = "Interop.Sys" and name = "LockType") // doesn't exist on osx +select getQualifiedName(qualifier, name), e.getUnderlyingType().toStringWithTypes() diff --git a/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql index ddc6671d358..5e27e9695a3 100644 --- a/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql +++ b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql @@ -1,5 +1,6 @@ import cil import semmle.code.cil.Type +import semmle.code.csharp.commons.QualifiedName bindingset[kind] private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" } @@ -26,9 +27,12 @@ query predicate params(string fnptr, int i, string param, string t) { } query predicate modifiers(string fnptr, string modifier, string sKind) { - exists(Type modType, int kind, FunctionPointerType fn | fnptr = fn.toString() | + exists(Type modType, int kind, FunctionPointerType fn, string qualifier, string name | + fnptr = fn.toString() + | cil_custom_modifiers(fn, modType, kind) and - modType.getQualifiedName() = modifier and + modType.hasQualifiedName(qualifier, name) and + modifier = getQualifiedName(qualifier, name) and sKind = getKind(kind) ) } diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql index 3366bef35ce..007a8f0f909 100644 --- a/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql +++ b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql @@ -1,13 +1,15 @@ import semmle.code.cil.Type +import semmle.code.csharp.commons.QualifiedName bindingset[kind] private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" } from string receiver, string modifier, int kind where - exists(Type modType, CustomModifierReceiver cmr | + exists(Type modType, CustomModifierReceiver cmr, string qualifier, string name | receiver = cmr.toString() and cil_custom_modifiers(cmr, modType, kind) and - modType.getQualifiedName() = modifier + modType.hasQualifiedName(qualifier, name) and + modifier = getQualifiedName(qualifier, name) ) select receiver, modifier, getKind(kind) diff --git a/csharp/ql/test/library-tests/cil/regressions/ConstructedMethods.ql b/csharp/ql/test/library-tests/cil/regressions/ConstructedMethods.ql index 15195dc0dd5..3ea940e2ef0 100644 --- a/csharp/ql/test/library-tests/cil/regressions/ConstructedMethods.ql +++ b/csharp/ql/test/library-tests/cil/regressions/ConstructedMethods.ql @@ -3,5 +3,5 @@ import cil::CIL from UnboundGenericMethod f, ConstructedMethod fc where fc.getUnboundMethod() = f and - f.getQualifiedName() = "Methods.Class1.F" + f.hasQualifiedName("Methods", "Class1", "F") select f, fc, fc.getTypeArgument(0) diff --git a/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql index 78dab812d72..8139aa7abfc 100644 --- a/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql +++ b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql @@ -1,26 +1,41 @@ import cil +import semmle.code.csharp.commons.QualifiedName import semmle.code.cil.Type private string elementType(Element e, string toString) { - toString = e.(Method).getQualifiedName() and result = "method" - or - toString = e.(Property).getQualifiedName() and result = "property" + exists(string namespace, string type, string name | + toString = getQualifiedName(namespace, type, name) + | + e.(Method).hasQualifiedName(namespace, type, name) and result = "method" + or + e.(Property).hasQualifiedName(namespace, type, name) and result = "property" + ) or e = any(Parameter p | - toString = "Parameter " + p.getIndex() + " of " + p.getDeclaringElement().getQualifiedName() + exists(string qualifier, string name | + p.getDeclaringElement().hasQualifiedName(qualifier, name) + | + toString = "Parameter " + p.getIndex() + " of " + getQualifiedName(qualifier, name) + ) ) and result = "parameter" or e = any(LocalVariable v | - toString = - "Local variable " + v.getIndex() + " of method " + - v.getImplementation().getMethod().getQualifiedName() + exists(string namespace, string type, string name | + v.getImplementation().getMethod().hasQualifiedName(namespace, type, name) + | + toString = + "Local variable " + v.getIndex() + " of method " + getQualifiedName(namespace, type, name) + ) ) and result = "local" or - toString = e.(FunctionPointerType).getQualifiedName() and result = "fnptr" + exists(string qualifier, string name | e.(FunctionPointerType).hasQualifiedName(qualifier, name) | + toString = getQualifiedName(qualifier, name) + ) and + result = "fnptr" or not e instanceof Method and not e instanceof Property and @@ -53,7 +68,9 @@ where ( not e instanceof Parameter or - e.(Parameter).getDeclaringElement().(Method).getDeclaringType().getQualifiedName() != - "System.Environment" // There are OS specific methods in this class + not exists(Type t | + t = e.(Parameter).getDeclaringElement().(Method).getDeclaringType() and + t.hasQualifiedName("System", "Environment") + ) // There are OS specific methods in this class ) select toString, type, i diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql index 6df087748d4..c2ef7845f3f 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql @@ -1,8 +1,10 @@ import cil import semmle.code.csharp.commons.Disposal +import semmle.code.csharp.commons.QualifiedName -from CIL::Field field +from CIL::Field field, string qualifier, string name where mayBeDisposed(field) and - field.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" -select field.getQualifiedName() + field.getDeclaringType().hasQualifiedName("DisposalTests", "Class1") and + field.hasQualifiedName(qualifier, name) +select getQualifiedName(qualifier, name) diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql index 97ca1ba7f2c..bc507851d8c 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql @@ -5,5 +5,5 @@ from DotNet::Callable c, DotNet::Parameter param, int p where mayBeDisposed(param) and param = c.getParameter(p) and - c.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" + c.getDeclaringType().hasQualifiedName("DisposalTests", "Class1") select c.toStringWithTypes(), p diff --git a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql index 9125fcd3d28..f4efb4e9921 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql @@ -6,5 +6,5 @@ from DotNet::Callable c, DotNet::Parameter param, int p where not mayBeDisposed(param) and param = c.getParameter(p) and - c.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" + c.getDeclaringType().hasQualifiedName("DisposalTests", "Class1") select c.toStringWithTypes(), p diff --git a/csharp/ql/test/library-tests/constructors/Destructors1.ql b/csharp/ql/test/library-tests/constructors/Destructors1.ql index f8b1fa9b6ef..52fe367c61d 100644 --- a/csharp/ql/test/library-tests/constructors/Destructors1.ql +++ b/csharp/ql/test/library-tests/constructors/Destructors1.ql @@ -3,9 +3,11 @@ */ import csharp +import semmle.code.csharp.commons.QualifiedName -from Destructor c +from Destructor c, string qualifier, string name where - c.getDeclaringType().getName() = "Class" and - c.getDeclaringType().getNamespace().getQualifiedName() = "Constructors" + c.getDeclaringType().hasQualifiedName(qualifier, name) and + qualifier = "Constructors" and + name = "Class" select c, c.getDeclaringType().getQualifiedName() diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index acabdc1835a..d5c2e78587d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -2775,7 +2775,7 @@ Assert.cs: #-----| true -> access to parameter b2 # 140| [assertion failure] access to parameter b2 -#-----| false -> [assertion failure] access to parameter b3 +#-----| false, true -> [assertion failure] access to parameter b3 # 140| access to parameter b2 #-----| false -> [assertion success] access to parameter b3 @@ -4924,7 +4924,7 @@ ExitMethods.cs: #-----| -> ...; # 22| call to method ErrorAlways -#-----| exception(Exception) -> exit M3 (abnormal) +#-----| exception(ArgumentException), exception(Exception) -> exit M3 (abnormal) # 22| ...; #-----| -> true diff --git a/csharp/ql/test/library-tests/csharp10/fileScopedNamespace.ql b/csharp/ql/test/library-tests/csharp10/fileScopedNamespace.ql index 5b955bdafcd..c4ca6874987 100644 --- a/csharp/ql/test/library-tests/csharp10/fileScopedNamespace.ql +++ b/csharp/ql/test/library-tests/csharp10/fileScopedNamespace.ql @@ -1,7 +1,7 @@ import csharp query predicate fileScopedNamespace(Namespace n, Member m) { - n.hasQualifiedName("MyFileScopedNamespace") and + n.hasQualifiedName("", "MyFileScopedNamespace") and exists(Class c | c.getNamespace() = n and c.hasMember(m) and diff --git a/csharp/ql/test/library-tests/csharp11/ListPattern.cs b/csharp/ql/test/library-tests/csharp11/ListPattern.cs new file mode 100644 index 00000000000..2bede367969 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/ListPattern.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; + +class ListPattern +{ + public void M1(int[] x) + { + if (x is []) { } + if (x is [1]) { } + if (x is [_, 2]) { } + if (x is [var y, 3, 4]) { } + if (x is [5 or 6, _, 7]) { } + if (x is [var a, .., 2]) { } + if (x is [var b, .. { Length: 2 or 5 }, 2]) { } + } + + public void M2(string[] x) + { + switch (x) + { + case []: + break; + case ["A"]: + break; + case [_, "B"]: + break; + case [var y, "C", "D"]: + break; + case ["E" or "F", _, "G"]: + break; + case [var a, .., "H"]: + break; + case [var b, .. var c, "I"]: + break; + default: + break; + } + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp11/NativeInt.cs b/csharp/ql/test/library-tests/csharp11/NativeInt.cs new file mode 100644 index 00000000000..5bee8213bdf --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/NativeInt.cs @@ -0,0 +1,11 @@ +public class NativeInt +{ + public void M1() + { + nint x1 = 0; + System.IntPtr x2 = (System.IntPtr)0; + + nuint y1 = 0; + System.UIntPtr y2 = (System.UIntPtr)0; + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp11/PatternMatchSpan.cs b/csharp/ql/test/library-tests/csharp11/PatternMatchSpan.cs new file mode 100644 index 00000000000..18a15f49f35 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/PatternMatchSpan.cs @@ -0,0 +1,19 @@ +using System; + +class PatternMatchSpan +{ + + public void M1(ReadOnlySpan x1) + { + if (x1 is "ABC") { } + } + + public void M2(Span x2) + { + switch (x2) + { + case "DEF": { break; } + default: { break; } + } + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp11/listPattern.expected b/csharp/ql/test/library-tests/csharp11/listPattern.expected new file mode 100644 index 00000000000..7fcaa6be75c --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/listPattern.expected @@ -0,0 +1,20 @@ +listPattern +| ListPattern.cs:7:18:7:19 | [ ... ] | | +| ListPattern.cs:8:18:8:20 | [ ... ] | 1 | +| ListPattern.cs:9:18:9:23 | [ ... ] | _, 2 | +| ListPattern.cs:10:18:10:30 | [ ... ] | Int32 y, 3, 4 | +| ListPattern.cs:11:18:11:31 | [ ... ] | ... or ..., _, 7 | +| ListPattern.cs:12:18:12:31 | [ ... ] | Int32 a, .., 2 | +| ListPattern.cs:13:18:13:50 | [ ... ] | Int32 b, .., 2 | +| ListPattern.cs:20:18:20:19 | [ ... ] | | +| ListPattern.cs:22:18:22:22 | [ ... ] | "A" | +| ListPattern.cs:24:18:24:25 | [ ... ] | _, "B" | +| ListPattern.cs:26:18:26:34 | [ ... ] | String y, "C", "D" | +| ListPattern.cs:28:18:28:37 | [ ... ] | ... or ..., _, "G" | +| ListPattern.cs:30:18:30:33 | [ ... ] | String a, .., "H" | +| ListPattern.cs:32:18:32:39 | [ ... ] | String b, .., "I" | +slicePattern +| ListPattern.cs:12:26:12:27 | .. | ..: | +| ListPattern.cs:13:26:13:46 | .. | ..:{ ... } | +| ListPattern.cs:30:26:30:27 | .. | ..: | +| ListPattern.cs:32:26:32:33 | .. | ..:String[] c | diff --git a/csharp/ql/test/library-tests/csharp11/listPattern.ql b/csharp/ql/test/library-tests/csharp11/listPattern.ql new file mode 100644 index 00000000000..005530f2c24 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/listPattern.ql @@ -0,0 +1,19 @@ +import csharp + +private string childPatterns(ListPatternExpr e) { + result = concat(string child, int n | child = e.getPattern(n).toString() | child, ", " order by n) +} + +query predicate listPattern(ListPatternExpr pattern, string children) { + pattern.getFile().getStem() = "ListPattern" and + children = childPatterns(pattern) +} + +query predicate slicePattern(SlicePatternExpr pattern, string s) { + pattern.getFile().getStem() = "ListPattern" and + exists(string child | + if exists(pattern.getPattern()) then child = pattern.getPattern().toString() else child = "" + | + s = pattern.toString() + ":" + child + ) +} diff --git a/csharp/ql/test/library-tests/csharp11/nativeInt.expected b/csharp/ql/test/library-tests/csharp11/nativeInt.expected new file mode 100644 index 00000000000..d376204b945 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/nativeInt.expected @@ -0,0 +1,4 @@ +| NativeInt.cs:5:14:5:15 | x1 | NativeInt.cs:6:23:6:24 | x2 | System.IntPtr | +| NativeInt.cs:6:23:6:24 | x2 | NativeInt.cs:5:14:5:15 | x1 | System.IntPtr | +| NativeInt.cs:8:15:8:16 | y1 | NativeInt.cs:9:24:9:25 | y2 | System.UIntPtr | +| NativeInt.cs:9:24:9:25 | y2 | NativeInt.cs:8:15:8:16 | y1 | System.UIntPtr | diff --git a/csharp/ql/test/library-tests/csharp11/nativeInt.ql b/csharp/ql/test/library-tests/csharp11/nativeInt.ql new file mode 100644 index 00000000000..c865833a452 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/nativeInt.ql @@ -0,0 +1,12 @@ +import csharp +import semmle.code.csharp.commons.QualifiedName + +from LocalVariable v1, LocalVariable v2, Type t, string qualifier, string name +where + v1.getFile().getStem() = "NativeInt" and + v2.getFile().getStem() = "NativeInt" and + t = v1.getType() and + t = v2.getType() and + t.hasQualifiedName(qualifier, name) and + v1 != v2 +select v1, v2, getQualifiedName(qualifier, name) diff --git a/csharp/ql/test/library-tests/csharp11/patternMatchSpan.expected b/csharp/ql/test/library-tests/csharp11/patternMatchSpan.expected new file mode 100644 index 00000000000..9b105349fca --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/patternMatchSpan.expected @@ -0,0 +1,2 @@ +| ReadOnlySpan | PatternMatchSpan.cs:8:19:8:23 | "ABC" | String | +| Span | PatternMatchSpan.cs:15:18:15:22 | "DEF" | String | diff --git a/csharp/ql/test/library-tests/csharp11/patternMatchSpan.ql b/csharp/ql/test/library-tests/csharp11/patternMatchSpan.ql new file mode 100644 index 00000000000..5f4d202c6f5 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp11/patternMatchSpan.ql @@ -0,0 +1,5 @@ +import csharp + +from PatternMatch pm +where pm.getFile().getStem() = "PatternMatchSpan" +select pm.getExpr().getType().getName(), pm.getPattern(), pm.getPattern().getType().getName() diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index d5302764f5c..af72c3e5e38 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -160,7 +160,7 @@ | CSharp7.cs:232:20:232:23 | null | CSharp7.cs:232:16:232:23 | SSA def(o) | | CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:233:18:233:23 | SSA def(i1) | | CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:237:18:237:18 | access to local variable o | -| CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:233:13:233:13 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | | CSharp7.cs:233:13:233:23 | [false] ... is ... | CSharp7.cs:233:13:233:33 | [false] ... && ... | | CSharp7.cs:233:13:233:23 | [true] ... is ... | CSharp7.cs:233:13:233:33 | [false] ... && ... | | CSharp7.cs:233:13:233:23 | [true] ... is ... | CSharp7.cs:233:13:233:33 | [true] ... && ... | @@ -173,13 +173,14 @@ | CSharp7.cs:235:38:235:39 | access to local variable i1 | CSharp7.cs:235:31:235:41 | $"..." | | CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:237:23:237:31 | SSA def(s1) | | CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:241:18:241:18 | access to local variable o | -| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | | CSharp7.cs:237:23:237:31 | SSA def(s1) | CSharp7.cs:239:41:239:42 | access to local variable s1 | | CSharp7.cs:239:33:239:39 | "string " | CSharp7.cs:239:31:239:44 | $"..." | | CSharp7.cs:239:41:239:42 | access to local variable s1 | CSharp7.cs:239:31:239:44 | $"..." | | CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:244:18:244:18 | access to local variable o | -| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | -| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:248:17:248:17 | access to local variable o | +| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | +| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:248:9:274:9 | SSA phi read(o) | +| CSharp7.cs:248:9:274:9 | SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:254:27:254:27 | access to local variable o | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:257:18:257:23 | SSA def(i2) | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:260:18:260:23 | SSA def(i3) | diff --git a/csharp/ql/test/library-tests/csharp9/PrintAst.expected b/csharp/ql/test/library-tests/csharp9/PrintAst.expected index 3c708935143..aeaea302fa3 100644 --- a/csharp/ql/test/library-tests/csharp9/PrintAst.expected +++ b/csharp/ql/test/library-tests/csharp9/PrintAst.expected @@ -5,7 +5,8 @@ AnonymousObjectCreation.cs: # 7| 1: [TypeMention] AnonObj # 7| 1: [AssignExpr] ... = ... # 7| 0: [FieldAccess] access to field l -# 7| 1: [ObjectCreation] object creation of type List +# 7| 1: [CastExpr] (...) ... +# 7| 1: [ObjectCreation] object creation of type List # 9| 6: [Property] Prop1 # 9| -1: [TypeMention] int # 9| 3: [Getter] get_Prop1 @@ -21,13 +22,15 @@ AnonymousObjectCreation.cs: # 13| 0: [ExprStmt] ...; # 13| 0: [MethodCall] call to method M1 # 13| -1: [ThisAccess] this access -# 13| 0: [ObjectCreation] object creation of type AnonObj -# 13| -1: [ObjectInitializer] { ..., ... } -# 13| 0: [MemberInitializer] ... = ... -# 13| 0: [PropertyCall] access to property Prop1 -# 13| 1: [IntLiteral] 1 +# 13| 0: [CastExpr] (...) ... +# 13| 1: [ObjectCreation] object creation of type AnonObj +# 13| -1: [ObjectInitializer] { ..., ... } +# 13| 0: [MemberInitializer] ... = ... +# 13| 0: [PropertyCall] access to property Prop1 +# 13| 1: [IntLiteral] 1 # 14| 1: [ReturnStmt] return ...; -# 14| 0: [ObjectCreation] object creation of type AnonObj +# 14| 0: [CastExpr] (...) ... +# 14| 1: [ObjectCreation] object creation of type AnonObj # 17| 8: [DelegateType] D #-----| 2: (Parameters) # 17| 0: [Parameter] x @@ -42,9 +45,10 @@ AnonymousObjectCreation.cs: # 21| -1: [TypeMention] D # 21| 4: [BlockStmt] {...} # 21| 0: [ReturnStmt] return ...; -# 21| 0: [ExplicitDelegateCreation] delegate creation of type D -# 21| 0: [ImplicitDelegateCreation] delegate creation of type D -# 21| 0: [MethodAccess] access to method M2 +# 21| 0: [CastExpr] (...) ... +# 21| 1: [ExplicitDelegateCreation] delegate creation of type D +# 21| 0: [ImplicitDelegateCreation] delegate creation of type D +# 21| 0: [MethodAccess] access to method M2 # 23| 11: [Method] MethodAdd # 23| -1: [TypeMention] Void # 24| 4: [BlockStmt] {...} @@ -53,7 +57,8 @@ AnonymousObjectCreation.cs: # 25| -1: [TypeMention] List # 25| 1: [TypeMention] int # 25| 0: [LocalVariableAccess] access to local variable list -# 25| 1: [ObjectCreation] object creation of type List +# 25| 1: [CastExpr] (...) ... +# 25| 1: [ObjectCreation] object creation of type List BinaryPattern.cs: # 3| [Class] BinaryPattern # 5| 5: [Property] P1 diff --git a/csharp/ql/test/library-tests/csharp9/covariantReturn.ql b/csharp/ql/test/library-tests/csharp9/covariantReturn.ql index f4958cbba31..a9f1107b050 100644 --- a/csharp/ql/test/library-tests/csharp9/covariantReturn.ql +++ b/csharp/ql/test/library-tests/csharp9/covariantReturn.ql @@ -1,8 +1,13 @@ import csharp +import semmle.code.csharp.commons.QualifiedName -from Method m, Method overrider +from + Method m, Method overrider, string mnamespace, string mtype, string mname, string onamespace, + string otype, string oname where m.getAnOverrider() = overrider and - m.getFile().getStem() = "CovariantReturn" -select m.getQualifiedName(), m.getReturnType().toString(), overrider.getQualifiedName(), - overrider.getReturnType().toString() + m.getFile().getStem() = "CovariantReturn" and + m.hasQualifiedName(mnamespace, mtype, mname) and + overrider.hasQualifiedName(onamespace, otype, oname) +select getQualifiedName(mnamespace, mtype, mname), m.getReturnType().toString(), + getQualifiedName(onamespace, otype, oname), overrider.getReturnType().toString() diff --git a/csharp/ql/test/library-tests/csharp9/foreach.ql b/csharp/ql/test/library-tests/csharp9/foreach.ql index 38d431d762f..2556d08bb1e 100644 --- a/csharp/ql/test/library-tests/csharp9/foreach.ql +++ b/csharp/ql/test/library-tests/csharp9/foreach.ql @@ -1,4 +1,5 @@ import csharp +import semmle.code.csharp.commons.QualifiedName private string getLocation(Member m) { if m.fromSource() then result = m.getALocation().(SourceLocation).toString() else result = "-" @@ -8,8 +9,13 @@ private string getIsAsync(ForeachStmt f) { if f.isAsync() then result = "async" else result = "sync" } -from ForeachStmt f -select f, f.getElementType().toString(), getIsAsync(f), - f.getGetEnumerator().getDeclaringType().getQualifiedName(), getLocation(f.getGetEnumerator()), - f.getCurrent().getDeclaringType().getQualifiedName(), getLocation(f.getCurrent()), - f.getMoveNext().getDeclaringType().getQualifiedName(), getLocation(f.getMoveNext()) +from + ForeachStmt f, string qualifier1, string type1, string qualifier2, string type2, + string qualifier3, string type3 +where + f.getGetEnumerator().getDeclaringType().hasQualifiedName(qualifier1, type1) and + f.getCurrent().getDeclaringType().hasQualifiedName(qualifier2, type2) and + f.getMoveNext().getDeclaringType().hasQualifiedName(qualifier3, type3) +select f, f.getElementType().toString(), getIsAsync(f), getQualifiedName(qualifier1, type1), + getLocation(f.getGetEnumerator()), getQualifiedName(qualifier2, type2), + getLocation(f.getCurrent()), getQualifiedName(qualifier3, type3), getLocation(f.getMoveNext()) diff --git a/csharp/ql/test/library-tests/csharp9/record.ql b/csharp/ql/test/library-tests/csharp9/record.ql index 7fc45550365..fb7b33fa286 100644 --- a/csharp/ql/test/library-tests/csharp9/record.ql +++ b/csharp/ql/test/library-tests/csharp9/record.ql @@ -1,4 +1,5 @@ import csharp +import semmle.code.csharp.commons.QualifiedName query predicate records(RecordClass t, string i, RecordCloneMethod clone) { t.getABaseInterface().toStringWithTypes() = i and @@ -7,7 +8,9 @@ query predicate records(RecordClass t, string i, RecordCloneMethod clone) { } private string getMemberName(Member m) { - result = m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes() + exists(string qualifier, string name | m.getDeclaringType().hasQualifiedName(qualifier, name) | + result = getQualifiedName(qualifier, name) + "." + m.toStringWithTypes() + ) } query predicate members(RecordClass t, string ms, string l) { diff --git a/csharp/ql/test/library-tests/csharp9/withExpr.ql b/csharp/ql/test/library-tests/csharp9/withExpr.ql index 7f51f85384b..8ae5265b058 100644 --- a/csharp/ql/test/library-tests/csharp9/withExpr.ql +++ b/csharp/ql/test/library-tests/csharp9/withExpr.ql @@ -1,7 +1,10 @@ import csharp +import semmle.code.csharp.commons.QualifiedName private string getSignature(Method m) { - result = m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes() + exists(string qualifier, string name | m.getDeclaringType().hasQualifiedName(qualifier, name) | + result = getQualifiedName(qualifier, name) + "." + m.toStringWithTypes() + ) } query predicate withExpr(WithExpr with, string type, Expr expr, ObjectInitializer init, string clone) { diff --git a/csharp/ql/test/library-tests/dataflow/async/Async.ql b/csharp/ql/test/library-tests/dataflow/async/Async.ql index 71799e22f8a..aef928038e1 100644 --- a/csharp/ql/test/library-tests/dataflow/async/Async.ql +++ b/csharp/ql/test/library-tests/dataflow/async/Async.ql @@ -14,7 +14,7 @@ class MySink extends DataFlow::ExprNode { class MySource extends DataFlow::ParameterNode { MySource() { exists(Parameter p | p = this.getParameter() | - p = any(Class c | c.hasQualifiedName("Test")).getAMethod().getAParameter() + p = any(Class c | c.hasQualifiedName("", "Test")).getAMethod().getAParameter() ) } } diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml new file mode 100644 index 00000000000..a1c2a2d4d66 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: + # "namespace", "type", "overrides", "name", "signature", "ext", "inputspec", "outputspec", "kind", "provenance" + - ["My.Qltest", "D", false, "StepArgRes", "(System.Object)","", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["My.Qltest", "D", false, "StepArgArg", "(System.Object,System.Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["My.Qltest", "D", false, "StepArgQual", "(System.Object)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["My.Qltest", "D", false, "StepFieldGetter", "()", "", "Argument[this].Field[My.Qltest.D.Field]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "D", false, "StepFieldSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Field[My.Qltest.D.Field]", "value", "manual"] + - ["My.Qltest", "D", false, "StepFieldSetter", "(System.Object)", "", "Argument[this]", "ReturnValue.Field[My.Qltest.D.Field2]", "value", "manual"] + - ["My.Qltest", "D", false, "StepPropertyGetter", "()", "", "Argument[this].Property[My.Qltest.D.Property]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "D", false, "StepPropertySetter", "(System.Object)", "", "Argument[0]", "Argument[this].Property[My.Qltest.D.Property]", "value", "manual"] + - ["My.Qltest", "D", false, "StepElementGetter", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["My.Qltest", "D", false, "StepElementSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["My.Qltest", "D", false, "Apply<,>", "(System.Func,S)", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Apply<,>", "(System.Func,S)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["My.Qltest", "D", false, "Apply2<>", "(System.Action,S,S)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Apply2<>", "(System.Action,S,S)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["My.Qltest", "D", false, "Parse", "(System.String,System.Int32)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["My.Qltest", "D", false, "Reverse", "(System.Object[])", "", "Argument[0].WithElement", "ReturnValue", "value", "manual"] + - ["My.Qltest", "E", true, "get_MyProp", "()", "", "Argument[this].Field[My.Qltest.E.MyField]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "E", true, "set_MyProp", "(System.Object)", "", "Argument[0]", "Argument[this].Field[My.Qltest.E.MyField]", "value", "manual"] + - ["My.Qltest", "G", false, "GeneratedFlow", "(System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] + - ["My.Qltest", "G", false, "GeneratedFlowArgs", "(System.Object,System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] + - ["My.Qltest", "G", false, "GeneratedFlowArgs", "(System.Object,System.Object)", "", "Argument[1]", "ReturnValue", "value", "generated"] + - ["My.Qltest", "G", false, "MixedFlowArgs", "(System.Object,System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] + - ["My.Qltest", "G", false, "MixedFlowArgs", "(System.Object,System.Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ext/test.model.yml b/csharp/ql/test/library-tests/dataflow/external-models/ext/test.model.yml deleted file mode 100644 index 5de0644e793..00000000000 --- a/csharp/ql/test/library-tests/dataflow/external-models/ext/test.model.yml +++ /dev/null @@ -1,85 +0,0 @@ -extensions: - - - addsTo: - pack: codeql/csharp-all - extensible: extSourceModel - data: - # "namespace", "type", "overrides", "name", "signature", "ext", "spec", "kind", "provenance", - - ["My.Qltest", "A", false, "Src1", "()", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", false, "Src1", "(System.String)", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", false, "Src1", "", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", false, "Src2", "()", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", false, "Src3", "()", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", true, "Src2", "()", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", true, "Src3", "()", "", "ReturnValue", "local", "manual"] - - ["My.Qltest", "A", false, "SrcArg", "(System.Object)", "", "Argument[0]", "local", "manual"] - - ["My.Qltest", "A", false, "SrcArg", "(System.Object)", "", "Argument", "local", "manual"] - - ["My.Qltest", "A", true, "SrcParam", "(System.Object)", "", "Parameter[0]", "local", "manual"] - - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "ReturnValue", "local", "manual"] - - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "Parameter", "local", "manual"] - - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "", "local", "manual"] - - ["My.Qltest", "A", false, "SrcTwoArg", "(System.String,System.String)", "", "ReturnValue", "local", "manual"] - - - addsTo: - pack: codeql/csharp-all - extensible: extSinkModel - data: - # "namespace", "type", "overrides", "name", "signature", "ext", "spec", "kind", "provenance" - - ["My.Qltest", "B", false, "Sink1", "(System.Object)", "", "Argument[0]", "code", "manual"] - - ["My.Qltest", "B", false, "SinkMethod", "()", "", "ReturnValue", "xss", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "ReturnValue", "html", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "Argument", "remote", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "", "sql", "manual"] - - # Summaries relevant for the ExternalFlow testcase. - - addsTo: - pack: codeql/csharp-all - extensible: extSummaryModel - data: - # "namespace", "type", "overrides", "name", "signature", "ext", "inputspec", "outputspec", "kind", "provenance" - - ["My.Qltest", "D", false, "StepArgRes", "(System.Object)","", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["My.Qltest", "D", false, "StepArgArg", "(System.Object,System.Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - - ["My.Qltest", "D", false, "StepArgQual", "(System.Object)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["My.Qltest", "D", false, "StepFieldGetter", "()", "", "Argument[this].Field[My.Qltest.D.Field]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "D", false, "StepFieldSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Field[My.Qltest.D.Field]", "value", "manual"] - - ["My.Qltest", "D", false, "StepFieldSetter", "(System.Object)", "", "Argument[this]", "ReturnValue.Field[My.Qltest.D.Field2]", "value", "manual"] - - ["My.Qltest", "D", false, "StepPropertyGetter", "()", "", "Argument[this].Property[My.Qltest.D.Property]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "D", false, "StepPropertySetter", "(System.Object)", "", "Argument[0]", "Argument[this].Property[My.Qltest.D.Property]", "value", "manual"] - - ["My.Qltest", "D", false, "StepElementGetter", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["My.Qltest", "D", false, "StepElementSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - - ["My.Qltest", "D", false, "Apply<,>", "(System.Func,S)", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] - - ["My.Qltest", "D", false, "Apply<,>", "(System.Func,S)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] - - ["My.Qltest", "D", false, "Apply2<>", "(System.Action,S,S)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"] - - ["My.Qltest", "D", false, "Apply2<>", "(System.Action,S,S)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"] - - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] - - ["My.Qltest", "D", false, "Parse", "(System.String,System.Int32)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - - ["My.Qltest", "D", false, "Reverse", "(System.Object[])", "", "Argument[0].WithElement", "ReturnValue", "value", "manual"] - - ["My.Qltest", "E", true, "get_MyProp", "()", "", "Argument[this].Field[My.Qltest.E.MyField]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "E", true, "set_MyProp", "(System.Object)", "", "Argument[0]", "Argument[this].Field[My.Qltest.E.MyField]", "value", "manual"] - - ["My.Qltest", "G", false, "GeneratedFlow", "(System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] - - ["My.Qltest", "G", false, "GeneratedFlowArgs", "(System.Object,System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] - - ["My.Qltest", "G", false, "GeneratedFlowArgs", "(System.Object,System.Object)", "", "Argument[1]", "ReturnValue", "value", "generated"] - - ["My.Qltest", "G", false, "MixedFlowArgs", "(System.Object,System.Object)", "", "Argument[0]", "ReturnValue", "value", "generated"] - - ["My.Qltest", "G", false, "MixedFlowArgs", "(System.Object,System.Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - - # Summaries relevant for the Steps testcase. - - addsTo: - pack: codeql/csharp-all - extensible: extSummaryModel - # "namespace", "type", "overrides", "name", "signature", "ext", "inputspec", "outputspec", "kind", "provenance" - data: - - ["My.Qltest", "C", false, "StepArgRes", "(System.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["My.Qltest", "C", false, "StepArgArg", "(System.Object,System.Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - - ["My.Qltest", "C", false, "StepArgQual", "(System.Object)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["My.Qltest", "C", false, "StepQualRes", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["My.Qltest", "C", false, "StepQualArg", "(System.Object)", "", "Argument[this]", "Argument[0]", "taint", "manual"] - - ["My.Qltest", "C", false, "StepFieldGetter", "()", "", "Argument[this].Field[My.Qltest.C.Field]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "C", false, "StepFieldSetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Field[My.Qltest.C.Field]", "value", "manual"] - - ["My.Qltest", "C", false, "StepPropertyGetter", "()", "", "Argument[this].Property[My.Qltest.C.Property]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "C", false, "StepPropertySetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Property[My.Qltest.C.Property]", "value", "manual"] - - ["My.Qltest", "C", false, "StepElementGetter", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["My.Qltest", "C", false, "StepElementSetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - - ["My.Qltest", "C+Generic<,>", false, "StepGeneric", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "C+Generic<,>", false, "StepGeneric2<>", "(S)", "", "Argument[0]", "ReturnValue", "value", "manual"] - - ["My.Qltest", "C+Base<>", true, "StepOverride", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml new file mode 100644 index 00000000000..3198057f42c --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: sinkModel + data: + # "namespace", "type", "overrides", "name", "signature", "ext", "spec", "kind", "provenance" + - ["My.Qltest", "B", false, "Sink1", "(System.Object)", "", "Argument[0]", "code", "manual"] + - ["My.Qltest", "B", false, "SinkMethod", "()", "", "ReturnValue", "xss", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "ReturnValue", "html", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "Argument", "remote", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "", "sql", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/external-models/srcs.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/srcs.ext.yml new file mode 100644 index 00000000000..163d2636ab0 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/external-models/srcs.ext.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: sourceModel + data: + # "namespace", "type", "overrides", "name", "signature", "ext", "spec", "kind", "provenance", + - ["My.Qltest", "A", false, "Src1", "()", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", false, "Src1", "(System.String)", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", false, "Src1", "", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", false, "Src2", "()", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", false, "Src3", "()", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", true, "Src2", "()", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", true, "Src3", "()", "", "ReturnValue", "local", "manual"] + - ["My.Qltest", "A", false, "SrcArg", "(System.Object)", "", "Argument[0]", "local", "manual"] + - ["My.Qltest", "A", false, "SrcArg", "(System.Object)", "", "Argument", "local", "manual"] + - ["My.Qltest", "A", true, "SrcParam", "(System.Object)", "", "Parameter[0]", "local", "manual"] + - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "ReturnValue", "local", "manual"] + - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "Parameter", "local", "manual"] + - ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "", "local", "manual"] + - ["My.Qltest", "A", false, "SrcTwoArg", "(System.String,System.String)", "", "ReturnValue", "local", "manual"] \ No newline at end of file diff --git a/csharp/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/steps.ext.yml new file mode 100644 index 00000000000..7507f5a8883 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + # "namespace", "type", "overrides", "name", "signature", "ext", "inputspec", "outputspec", "kind", "provenance" + data: + - ["My.Qltest", "C", false, "StepArgRes", "(System.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["My.Qltest", "C", false, "StepArgArg", "(System.Object,System.Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["My.Qltest", "C", false, "StepArgQual", "(System.Object)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["My.Qltest", "C", false, "StepQualRes", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["My.Qltest", "C", false, "StepQualArg", "(System.Object)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["My.Qltest", "C", false, "StepFieldGetter", "()", "", "Argument[this].Field[My.Qltest.C.Field]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "C", false, "StepFieldSetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Field[My.Qltest.C.Field]", "value", "manual"] + - ["My.Qltest", "C", false, "StepPropertyGetter", "()", "", "Argument[this].Property[My.Qltest.C.Property]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "C", false, "StepPropertySetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Property[My.Qltest.C.Property]", "value", "manual"] + - ["My.Qltest", "C", false, "StepElementGetter", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["My.Qltest", "C", false, "StepElementSetter", "(System.Int32)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["My.Qltest", "C+Generic<,>", false, "StepGeneric", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "C+Generic<,>", false, "StepGeneric2<>", "(S)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["My.Qltest", "C+Base<>", true, "StepOverride", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql index 2e216a672d7..f7635eae882 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql +++ b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql @@ -6,30 +6,24 @@ import semmle.code.csharp.dataflow.FlowSummary import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlowDispatch import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -private SummarizedCallable getRelevantSummarizedCallable() { - exists(SummarizedCallable sc | - sc.getDeclaringType*().getName() = "C" and - sc instanceof DataFlowDispatch::DataFlowSummarizedCallable and - result = sc - ) -} - query predicate summaryThroughStep( DataFlow::Node node1, DataFlow::Node node2, boolean preservesValue ) { FlowSummaryImpl::Private::Steps::summaryThroughStepValue(node1, node2, - getRelevantSummarizedCallable()) and + any(DataFlowDispatch::DataFlowSummarizedCallable sc)) and preservesValue = true or FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, - getRelevantSummarizedCallable()) and + any(DataFlowDispatch::DataFlowSummarizedCallable sc)) and preservesValue = false } query predicate summaryGetterStep(DataFlow::Node arg, DataFlow::Node out, Content c) { - FlowSummaryImpl::Private::Steps::summaryGetterStep(arg, c, out, getRelevantSummarizedCallable()) + FlowSummaryImpl::Private::Steps::summaryGetterStep(arg, c, out, + any(DataFlowDispatch::DataFlowSummarizedCallable sc)) } query predicate summarySetterStep(DataFlow::Node arg, DataFlow::Node out, Content c) { - FlowSummaryImpl::Private::Steps::summarySetterStep(arg, c, out, getRelevantSummarizedCallable()) + FlowSummaryImpl::Private::Steps::summarySetterStep(arg, c, out, + any(DataFlowDispatch::DataFlowSummarizedCallable sc)) } diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTracking.ql b/csharp/ql/test/library-tests/dataflow/global/TaintTracking.ql index 1fc9bb63fc2..43284a3d198 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTracking.ql +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTracking.ql @@ -1,14 +1,10 @@ import csharp import Common -class TTConfig extends TaintTracking::Configuration { - Config c; +class TTConfig extends TaintTracking::Configuration instanceof Config { + override predicate isSource(DataFlow::Node source) { Config.super.isSource(source) } - TTConfig() { this = c } - - override predicate isSource(DataFlow::Node source) { c.isSource(source) } - - override predicate isSink(DataFlow::Node sink) { c.isSink(sink) } + override predicate isSink(DataFlow::Node sink) { Config.super.isSink(sink) } } from TTConfig c, DataFlow::Node source, DataFlow::Node sink diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.ql b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.ql index e0eccb70461..3764c14789c 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.ql +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.ql @@ -6,14 +6,10 @@ import csharp import Common import DataFlow::PathGraph -class TTConfig extends TaintTracking::Configuration { - Config c; +class TTConfig extends TaintTracking::Configuration instanceof Config { + override predicate isSource(DataFlow::Node source) { Config.super.isSource(source) } - TTConfig() { this = c } - - override predicate isSource(DataFlow::Node source) { c.isSource(source) } - - override predicate isSink(DataFlow::Node sink) { c.isSink(sink) } + override predicate isSink(DataFlow::Node sink) { Config.super.isSink(sink) } } from TTConfig c, DataFlow::PathNode source, DataFlow::PathNode sink, string s diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index fcdf91118e1..ad09add3853 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -11928,7 +11928,7 @@ summary | System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated | | System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual | | System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual | -negativeSummary +neutral | Microsoft.CSharp.RuntimeBinder;CSharpArgumentInfo;Create;(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,System.String);generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;();generated | | Microsoft.CSharp.RuntimeBinder;RuntimeBinderException;RuntimeBinderException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql index 717c4943f46..eaf4d9d947f 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql @@ -6,11 +6,7 @@ private class IncludeAllSummarizedCallable extends IncludeSummarizedCallable { IncludeAllSummarizedCallable() { exists(this) } } -private class IncludeNegativeSummarizedCallable extends RelevantNegativeSummarizedCallable { - IncludeNegativeSummarizedCallable() { - this instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable - } - +private class IncludeNeutralCallable extends RelevantNeutralCallable instanceof FlowSummaryImpl::Public::NeutralCallable { /** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */ - final override string getCallableCsv() { result = Csv::asPartialNegativeModel(this) } + final override string getCallableCsv() { result = Csv::asPartialNeutralModel(this) } } diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 7ad542d4668..880a71ca5d0 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -10262,4 +10262,4 @@ summary | System;ValueTuple<>;false;ToString;();;Argument[this];ReturnValue;taint;generated | | System;ValueTuple<>;false;ValueTuple;(T1);;Argument[0];Argument[this].Field[System.ValueTuple<>.Item1];value;manual | | System;ValueTuple<>;false;get_Item;(System.Int32);;Argument[this].Field[System.ValueTuple<>.Item1];ReturnValue;value;manual | -negativeSummary +neutral diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql index 961faf60084..82cf263ec9c 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql @@ -2,9 +2,7 @@ import shared.FlowSummaries private import semmle.code.csharp.dataflow.internal.DataFlowPrivate::Csv private import semmle.code.csharp.dataflow.ExternalFlow -class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable { - IncludeFilteredSummarizedCallable() { this instanceof SummarizedCallable } - +class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable instanceof SummarizedCallable { /** * Holds if flow is propagated between `input` and `output` and * if there is no summary for a callable in a `base` class or interface @@ -13,7 +11,7 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable { override predicate relevantSummary( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - this.(SummarizedCallable).propagatesFlow(input, output, preservesValue) and + super.propagatesFlow(input, output, preservesValue) and not exists(IncludeSummarizedCallable rsc | isBaseCallableOrPrototype(rsc) and rsc.(SummarizedCallable).propagatesFlow(input, output, preservesValue) and diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 92d2013bfbe..afb49ad2bce 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -373,8 +373,8 @@ | LocalDataFlow.cs:278:15:278:22 | access to local variable nonSink0 | LocalDataFlow.cs:285:31:285:38 | access to local variable nonSink0 | | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | LocalDataFlow.cs:282:15:282:20 | access to local variable sink70 | | LocalDataFlow.cs:281:22:281:34 | ... = ... | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | +| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | -| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | ... = ... | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | | LocalDataFlow.cs:282:15:282:20 | [post] access to local variable sink70 | LocalDataFlow.cs:289:13:289:18 | access to local variable sink70 | @@ -399,8 +399,9 @@ | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | LocalDataFlow.cs:313:13:313:38 | SSA def(sink73) | +| LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | -| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | +| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | LocalDataFlow.cs:316:15:316:20 | access to local variable sink74 | | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | @@ -441,28 +442,22 @@ | SSA.cs:13:15:13:22 | [post] access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:13:15:13:22 | access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:22:27:22:28 | "" | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | | SSA.cs:23:13:23:22 | [post] access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | | SSA.cs:23:13:23:22 | access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:28:16:28:28 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:28:27:28:28 | "" | SSA.cs:28:16:28:28 | SSA def(nonSink1) | @@ -470,43 +465,48 @@ | SSA.cs:29:13:29:22 | access to parameter nonTainted | SSA.cs:35:13:35:22 | access to parameter nonTainted | | SSA.cs:30:13:30:31 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:30:13:30:31 | SSA def(nonSink1) | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:49:24:49:31 | access to local variable nonSink0 | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | SSA.cs:31:15:31:22 | access to local variable nonSink1 | | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:34:27:34:28 | "" | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | | SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | -| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | +| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | +| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:39:21:39:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | +| SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | | SSA.cs:46:16:46:28 | SSA def(nonSink2) | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:46:27:46:28 | "" | SSA.cs:46:16:46:28 | SSA def(nonSink2) | | SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:51:21:51:28 | access to local variable nonSink2 | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:53:21:53:28 | access to local variable nonSink2 | | SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:49:13:49:31 | SSA def(nonSink2) | -| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | -| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | -| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | +| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | +| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:51:21:51:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:51:21:51:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | +| SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | SSA.cs:89:13:89:22 | access to parameter nonTainted | | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | SSA.cs:55:15:55:22 | access to local variable nonSink2 | | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 | | SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | @@ -555,9 +555,9 @@ | SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted | | SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 | | SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:80:9:80:12 | [post] this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:12 | this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:14 | [post] access to field S | SSA.cs:81:21:81:26 | access to field S | @@ -585,19 +585,21 @@ | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:88:27:88:28 | "" | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | | SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | -| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | -| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | +| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | +| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:93:21:93:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | +| SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | SSA.cs:97:23:97:30 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | @@ -605,19 +607,21 @@ | SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:28 | SSA def(nonSink3) | | SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:106:21:106:28 | access to local variable nonSink3 | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:108:21:108:28 | access to local variable nonSink3 | | SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:104:13:104:31 | SSA def(nonSink3) | -| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | -| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | -| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | +| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | +| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:106:21:106:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | +| SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | SSA.cs:115:13:115:22 | access to parameter nonTainted | | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) | @@ -627,15 +631,15 @@ | SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access | | SSA.cs:114:9:114:12 | this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | | SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:119:21:119:24 | this access | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:121:21:121:24 | this access | | SSA.cs:117:13:117:16 | this access | SSA.cs:119:21:119:24 | this access | @@ -647,20 +651,22 @@ | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | -| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | -| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | +| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:119:21:119:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | +| SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:123:9:123:30 | SSA phi read(this.S) | SSA.cs:123:23:123:28 | access to field S | | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | | SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access | | SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access | @@ -677,9 +683,9 @@ | SSA.cs:127:9:127:12 | this access | SSA.cs:130:13:130:16 | this access | | SSA.cs:127:9:127:12 | this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted | @@ -697,16 +703,17 @@ | SSA.cs:130:39:130:46 | access to local variable nonSink0 | SSA.cs:130:13:130:46 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | +| SSA.cs:136:9:136:30 | SSA phi read(this.S) | SSA.cs:136:23:136:28 | access to field S | | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | | SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access | | SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access | @@ -732,17 +739,16 @@ | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:176:21:176:28 | [post] access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | +| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 | | Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted | @@ -826,3 +832,1604 @@ | Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y | | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): false] access to local variable s | | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s | +| UseUseExplosion.cs:21:10:21:10 | SSA entry def(this.Prop) | UseUseExplosion.cs:24:13:24:16 | access to property Prop | +| UseUseExplosion.cs:21:10:21:10 | this | UseUseExplosion.cs:24:13:24:16 | this access | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:23:17:23:17 | 0 | UseUseExplosion.cs:23:13:23:17 | SSA def(x) | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:31:24:34 | access to property Prop | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:48:24:51 | access to property Prop | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:65:24:68 | access to property Prop | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:82:24:85 | access to property Prop | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:99:24:102 | access to property Prop | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:116:24:119 | access to property Prop | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:133:24:136 | access to property Prop | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:150:24:153 | access to property Prop | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:167:24:170 | access to property Prop | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:184:24:187 | access to property Prop | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:201:24:204 | access to property Prop | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:218:24:221 | access to property Prop | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:235:24:238 | access to property Prop | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:252:24:255 | access to property Prop | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:269:24:272 | access to property Prop | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:286:24:289 | access to property Prop | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:303:24:306 | access to property Prop | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:320:24:323 | access to property Prop | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:337:24:340 | access to property Prop | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:354:24:357 | access to property Prop | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:371:24:374 | access to property Prop | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:388:24:391 | access to property Prop | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:405:24:408 | access to property Prop | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:422:24:425 | access to property Prop | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:439:24:442 | access to property Prop | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:456:24:459 | access to property Prop | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:473:24:476 | access to property Prop | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:490:24:493 | access to property Prop | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:507:24:510 | access to property Prop | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:524:24:527 | access to property Prop | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:541:24:544 | access to property Prop | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:558:24:561 | access to property Prop | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:575:24:578 | access to property Prop | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:592:24:595 | access to property Prop | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:609:24:612 | access to property Prop | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:626:24:629 | access to property Prop | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:643:24:646 | access to property Prop | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:660:24:663 | access to property Prop | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:677:24:680 | access to property Prop | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:694:24:697 | access to property Prop | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:711:24:714 | access to property Prop | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:728:24:731 | access to property Prop | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:745:24:748 | access to property Prop | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:762:24:765 | access to property Prop | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:779:24:782 | access to property Prop | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:796:24:799 | access to property Prop | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:813:24:816 | access to property Prop | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:830:24:833 | access to property Prop | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:847:24:850 | access to property Prop | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:864:24:867 | access to property Prop | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:881:24:884 | access to property Prop | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:898:24:901 | access to property Prop | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:915:24:918 | access to property Prop | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:932:24:935 | access to property Prop | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:949:24:952 | access to property Prop | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:966:24:969 | access to property Prop | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:983:24:986 | access to property Prop | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1723:24:1728 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1723:24:1728 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1738:24:1743 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1738:24:1743 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1753:24:1758 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1753:24:1758 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1768:24:1773 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1768:24:1773 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1783:24:1788 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1783:24:1788 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1798:24:1803 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1798:24:1803 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1813:24:1818 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1813:24:1818 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1828:24:1833 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1828:24:1833 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1843:24:1848 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1843:24:1848 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1858:24:1863 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1858:24:1863 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1873:24:1878 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1873:24:1878 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1888:24:1893 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1888:24:1893 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1903:24:1908 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1903:24:1908 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1918:24:1923 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1918:24:1923 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1933:24:1938 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1933:24:1938 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1948:24:1953 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1948:24:1953 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1963:24:1968 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1963:24:1968 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1978:24:1983 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1978:24:1983 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1993:24:1998 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1993:24:1998 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2008:24:2013 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2008:24:2013 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2023:24:2028 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2023:24:2028 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2038:24:2043 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2038:24:2043 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2053:24:2058 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2053:24:2058 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2068:24:2073 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2068:24:2073 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2083:24:2088 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2083:24:2088 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2098:24:2103 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2098:24:2103 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2113:24:2118 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2113:24:2118 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2128:24:2133 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2128:24:2133 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2143:24:2148 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2143:24:2148 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2158:24:2163 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2158:24:2163 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2173:24:2178 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2173:24:2178 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2188:24:2193 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2188:24:2193 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2203:24:2208 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2203:24:2208 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2218:24:2223 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2218:24:2223 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2233:24:2238 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2233:24:2238 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2248:24:2253 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2248:24:2253 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2263:24:2268 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2263:24:2268 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2278:24:2283 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2278:24:2283 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2293:24:2298 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2293:24:2298 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2308:24:2313 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2308:24:2313 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2323:24:2328 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2323:24:2328 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2338:24:2343 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2338:24:2343 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2353:24:2358 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2353:24:2358 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2368:24:2373 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2368:24:2373 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2383:24:2388 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2383:24:2388 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2398:24:2403 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2398:24:2403 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2413:24:2418 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2413:24:2418 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2428:24:2433 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2428:24:2433 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2443:24:2448 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2443:24:2448 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2458:24:2463 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2458:24:2463 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2473:24:2478 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2473:24:2478 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2488:24:2493 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2488:24:2493 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2503:24:2508 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2503:24:2508 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2518:24:2523 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2518:24:2523 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2533:24:2538 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2533:24:2538 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2548:24:2553 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2548:24:2553 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2563:24:2568 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2563:24:2568 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2578:24:2583 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2578:24:2583 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2593:24:2598 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2593:24:2598 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2608:24:2613 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2608:24:2613 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2623:24:2628 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2623:24:2628 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2638:24:2643 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2638:24:2643 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2653:24:2658 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2653:24:2658 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2668:24:2673 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2668:24:2673 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2683:24:2688 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2683:24:2688 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2698:24:2703 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2698:24:2703 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2713:24:2718 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2713:24:2718 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2728:24:2733 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2728:24:2733 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2743:24:2748 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2743:24:2748 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2758:24:2763 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2758:24:2763 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2773:24:2778 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2773:24:2778 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2788:24:2793 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2788:24:2793 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2803:24:2808 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2803:24:2808 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2818:24:2823 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2818:24:2823 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2833:24:2838 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2833:24:2838 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2848:24:2853 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2848:24:2853 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2863:24:2868 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2863:24:2868 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2878:24:2883 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2878:24:2883 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2893:24:2898 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2893:24:2898 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2908:24:2913 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2908:24:2913 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2923:24:2928 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2923:24:2928 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2938:24:2943 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2938:24:2943 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2953:24:2958 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2953:24:2958 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2968:24:2973 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2968:24:2973 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2983:24:2988 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2983:24:2988 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2998:24:3003 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2998:24:3003 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3013:24:3018 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3013:24:3018 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3028:24:3033 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3028:24:3033 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3043:24:3048 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3043:24:3048 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3058:24:3063 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3058:24:3063 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3073:24:3078 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3073:24:3078 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3088:24:3093 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3088:24:3093 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3103:24:3108 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3103:24:3108 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3118:24:3123 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3118:24:3123 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3133:24:3138 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3133:24:3138 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3148:24:3153 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3148:24:3153 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3163:24:3168 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3163:24:3168 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3178:24:3183 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3178:24:3183 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3193:24:3198 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3193:24:3198 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | UseUseExplosion.cs:25:13:25:16 | access to property Prop | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1712:25:1712 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1727:25:1727 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1742:25:1742 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1757:25:1757 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1772:25:1772 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1787:25:1787 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1802:25:1802 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1817:25:1817 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1832:25:1832 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1847:25:1847 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1862:25:1862 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1877:25:1877 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1892:25:1892 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1907:25:1907 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1922:25:1922 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1937:25:1937 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1952:25:1952 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1967:25:1967 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1982:25:1982 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1997:25:1997 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2012:25:2012 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2027:25:2027 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2042:25:2042 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2057:25:2057 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2072:25:2072 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2087:25:2087 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2102:25:2102 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2117:25:2117 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2132:25:2132 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2147:25:2147 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2162:25:2162 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2177:25:2177 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2192:25:2192 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2207:25:2207 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2222:25:2222 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2237:25:2237 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2252:25:2252 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2267:25:2267 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2282:25:2282 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2297:25:2297 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2312:25:2312 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2327:25:2327 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2342:25:2342 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2357:25:2357 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2372:25:2372 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2387:25:2387 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2402:25:2402 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2417:25:2417 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2432:25:2432 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2447:25:2447 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2462:25:2462 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2477:25:2477 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2492:25:2492 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2507:25:2507 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2522:25:2522 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2537:25:2537 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2552:25:2552 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2567:25:2567 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2582:25:2582 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2597:25:2597 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2612:25:2612 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2627:25:2627 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2642:25:2642 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2657:25:2657 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2672:25:2672 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2687:25:2687 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2702:25:2702 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2717:25:2717 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2732:25:2732 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2747:25:2747 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2762:25:2762 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2777:25:2777 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2792:25:2792 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2807:25:2807 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2822:25:2822 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2837:25:2837 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2852:25:2852 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2867:25:2867 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2882:25:2882 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2897:25:2897 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2912:25:2912 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2927:25:2927 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2942:25:2942 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2957:25:2957 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2972:25:2972 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2987:25:2987 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3002:25:3002 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3017:25:3017 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3032:25:3032 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3047:25:3047 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3062:25:3062 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3077:25:3077 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3092:25:3092 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3107:25:3107 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3122:25:3122 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3137:25:3137 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3152:25:3152 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3167:25:3167 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3182:25:3182 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3197:25:3197 | access to local variable x | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:31:25:34 | access to property Prop | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:48:25:51 | access to property Prop | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:65:25:68 | access to property Prop | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:82:25:85 | access to property Prop | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:99:25:102 | access to property Prop | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:116:25:119 | access to property Prop | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:133:25:136 | access to property Prop | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:150:25:153 | access to property Prop | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:167:25:170 | access to property Prop | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:184:25:187 | access to property Prop | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:201:25:204 | access to property Prop | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:218:25:221 | access to property Prop | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:235:25:238 | access to property Prop | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:252:25:255 | access to property Prop | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:269:25:272 | access to property Prop | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:286:25:289 | access to property Prop | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:303:25:306 | access to property Prop | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:320:25:323 | access to property Prop | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:337:25:340 | access to property Prop | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:354:25:357 | access to property Prop | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:371:25:374 | access to property Prop | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:388:25:391 | access to property Prop | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:405:25:408 | access to property Prop | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:422:25:425 | access to property Prop | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:439:25:442 | access to property Prop | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:456:25:459 | access to property Prop | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:473:25:476 | access to property Prop | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:490:25:493 | access to property Prop | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:507:25:510 | access to property Prop | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:524:25:527 | access to property Prop | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:541:25:544 | access to property Prop | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:558:25:561 | access to property Prop | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:575:25:578 | access to property Prop | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:592:25:595 | access to property Prop | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:609:25:612 | access to property Prop | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:626:25:629 | access to property Prop | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:643:25:646 | access to property Prop | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:660:25:663 | access to property Prop | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:677:25:680 | access to property Prop | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:694:25:697 | access to property Prop | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:711:25:714 | access to property Prop | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:728:25:731 | access to property Prop | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:745:25:748 | access to property Prop | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:762:25:765 | access to property Prop | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:779:25:782 | access to property Prop | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:796:25:799 | access to property Prop | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:813:25:816 | access to property Prop | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:830:25:833 | access to property Prop | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:847:25:850 | access to property Prop | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:864:25:867 | access to property Prop | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:881:25:884 | access to property Prop | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:898:25:901 | access to property Prop | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:915:25:918 | access to property Prop | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:932:25:935 | access to property Prop | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:949:25:952 | access to property Prop | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:966:25:969 | access to property Prop | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:983:25:986 | access to property Prop | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | [post] this access | UseUseExplosion.cs:25:1708:25:1713 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | this access | UseUseExplosion.cs:25:1708:25:1713 | this access | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index a2767b538f5..dc8cdffaa36 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -482,8 +482,8 @@ | LocalDataFlow.cs:278:15:278:22 | access to local variable nonSink0 | LocalDataFlow.cs:285:31:285:38 | access to local variable nonSink0 | | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | LocalDataFlow.cs:282:15:282:20 | access to local variable sink70 | | LocalDataFlow.cs:281:22:281:34 | ... = ... | LocalDataFlow.cs:281:13:281:34 | SSA def(sink70) | +| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | -| LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | ... = ... | | LocalDataFlow.cs:281:30:281:34 | access to local variable sink0 | LocalDataFlow.cs:281:22:281:34 | SSA def(sink0) | | LocalDataFlow.cs:282:15:282:20 | [post] access to local variable sink70 | LocalDataFlow.cs:289:13:289:18 | access to local variable sink70 | @@ -508,8 +508,9 @@ | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | | LocalDataFlow.cs:313:22:313:29 | access to local variable nonSink0 | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | LocalDataFlow.cs:313:13:313:38 | SSA def(sink73) | +| LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | | LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | ... ?? ... | -| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | +| LocalDataFlow.cs:313:34:313:38 | access to local variable sink0 | LocalDataFlow.cs:313:22:313:38 | SSA phi read(sink0) | | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | LocalDataFlow.cs:316:15:316:20 | access to local variable sink74 | | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | @@ -551,19 +552,13 @@ | SSA.cs:13:15:13:22 | [post] access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:13:15:13:22 | access to local variable nonSink0 | SSA.cs:19:13:19:20 | access to local variable nonSink0 | | SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | [post] access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:16:13:16:20 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | | SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | [post] access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:30:24:30:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:19:13:19:20 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:22:27:22:28 | "" | SSA.cs:22:16:22:28 | SSA def(ssaSink1) | | SSA.cs:23:13:23:22 | [post] access to parameter nonTainted | SSA.cs:29:13:29:22 | access to parameter nonTainted | @@ -571,9 +566,9 @@ | SSA.cs:23:13:23:29 | access to property Length | SSA.cs:23:13:23:33 | ... > ... | | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | | SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:24:13:24:31 | SSA def(ssaSink1) | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | +| SSA.cs:24:24:24:31 | access to local variable ssaSink0 | SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | +| SSA.cs:25:9:25:24 | SSA phi read(ssaSink0) | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | | SSA.cs:25:9:25:24 | SSA phi(ssaSink1) | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:28:16:28:28 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:28:27:28:28 | "" | SSA.cs:28:16:28:28 | SSA def(nonSink1) | @@ -582,47 +577,52 @@ | SSA.cs:29:13:29:29 | access to property Length | SSA.cs:29:13:29:33 | ... > ... | | SSA.cs:30:13:30:31 | SSA def(nonSink1) | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | | SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:30:13:30:31 | SSA def(nonSink1) | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:49:24:49:31 | access to local variable nonSink0 | -| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:30:24:30:31 | access to local variable nonSink0 | SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:49:24:49:31 | access to local variable nonSink0 | +| SSA.cs:31:9:31:24 | SSA phi read(nonSink0) | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | | SSA.cs:31:9:31:24 | SSA phi(nonSink1) | SSA.cs:31:15:31:22 | access to local variable nonSink1 | | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:34:27:34:28 | "" | SSA.cs:34:16:34:28 | SSA def(ssaSink2) | | SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:38:17:38:26 | access to parameter nonTainted | -| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:35:13:35:22 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:35:13:35:29 | access to property Length | SSA.cs:35:13:35:33 | ... > ... | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | | SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:37:13:37:31 | SSA def(ssaSink2) | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | -| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | -| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:37:24:37:31 | access to local variable ssaSink0 | SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | +| SSA.cs:38:17:38:26 | [post] access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | +| SSA.cs:38:17:38:26 | access to parameter nonTainted | SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | | SSA.cs:38:17:38:33 | access to property Length | SSA.cs:38:17:38:37 | ... > ... | | SSA.cs:39:21:39:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:39:21:39:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | [post] access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | | SSA.cs:41:21:41:28 | access to local variable ssaSink2 | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | +| SSA.cs:43:9:43:24 | SSA phi read(nonTainted) | SSA.cs:47:13:47:22 | access to parameter nonTainted | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | +| SSA.cs:43:9:43:24 | SSA phi read(ssaSink0) | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | | SSA.cs:43:9:43:24 | SSA phi(ssaSink2) | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | | SSA.cs:46:16:46:28 | SSA def(nonSink2) | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:46:27:46:28 | "" | SSA.cs:46:16:46:28 | SSA def(nonSink2) | | SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:50:17:50:26 | access to parameter nonTainted | -| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:47:13:47:22 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:47:13:47:29 | access to property Length | SSA.cs:47:13:47:33 | ... > ... | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:51:21:51:28 | access to local variable nonSink2 | | SSA.cs:49:13:49:31 | SSA def(nonSink2) | SSA.cs:53:21:53:28 | access to local variable nonSink2 | | SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:49:13:49:31 | SSA def(nonSink2) | -| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | access to local variable nonSink0 | -| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | -| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:89:13:89:22 | access to parameter nonTainted | +| SSA.cs:49:24:49:31 | access to local variable nonSink0 | SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | +| SSA.cs:50:17:50:26 | [post] access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | +| SSA.cs:50:17:50:26 | access to parameter nonTainted | SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | | SSA.cs:50:17:50:33 | access to property Length | SSA.cs:50:17:50:37 | ... > ... | | SSA.cs:51:21:51:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:51:21:51:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | [post] access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | | SSA.cs:53:21:53:28 | access to local variable nonSink2 | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | +| SSA.cs:55:9:55:24 | SSA phi read(nonSink0) | SSA.cs:63:23:63:30 | access to local variable nonSink0 | +| SSA.cs:55:9:55:24 | SSA phi read(nonTainted) | SSA.cs:89:13:89:22 | access to parameter nonTainted | | SSA.cs:55:9:55:24 | SSA phi(nonSink2) | SSA.cs:55:15:55:22 | access to local variable nonSink2 | | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 | | SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:33 | SSA def(ssaSink3) | @@ -671,9 +671,9 @@ | SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted | | SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 | | SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 | -| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | | SSA.cs:80:9:80:12 | [post] this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:12 | this access | SSA.cs:81:21:81:24 | this access | | SSA.cs:80:9:80:14 | [post] access to field S | SSA.cs:81:21:81:26 | access to field S | @@ -701,21 +701,23 @@ | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:88:27:88:28 | "" | SSA.cs:88:16:88:28 | SSA def(ssaSink4) | | SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:92:17:92:26 | access to parameter nonTainted | -| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:89:13:89:22 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:89:13:89:29 | access to property Length | SSA.cs:89:13:89:33 | ... > ... | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | | SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:91:13:91:31 | SSA def(ssaSink4) | -| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | -| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | -| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:91:24:91:31 | access to local variable ssaSink0 | SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | +| SSA.cs:92:17:92:26 | [post] access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | +| SSA.cs:92:17:92:26 | access to parameter nonTainted | SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | | SSA.cs:92:17:92:33 | access to property Length | SSA.cs:92:17:92:37 | ... > ... | | SSA.cs:93:21:93:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | | SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | +| SSA.cs:97:9:97:32 | SSA phi read(nonTainted) | SSA.cs:102:13:102:22 | access to parameter nonTainted | +| SSA.cs:97:9:97:32 | SSA phi read(ssaSink0) | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | | SSA.cs:97:9:97:32 | SSA phi(ssaSink4) | SSA.cs:97:23:97:30 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 | | SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) | @@ -723,21 +725,23 @@ | SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:28 | SSA def(nonSink3) | | SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:105:17:105:26 | access to parameter nonTainted | -| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:102:13:102:22 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:102:13:102:29 | access to property Length | SSA.cs:102:13:102:33 | ... > ... | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:106:21:106:28 | access to local variable nonSink3 | | SSA.cs:104:13:104:31 | SSA def(nonSink3) | SSA.cs:108:21:108:28 | access to local variable nonSink3 | | SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:104:13:104:31 | SSA def(nonSink3) | -| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:130:39:130:46 | access to local variable nonSink0 | -| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | -| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:115:13:115:22 | access to parameter nonTainted | +| SSA.cs:104:24:104:31 | access to local variable nonSink0 | SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | +| SSA.cs:105:17:105:26 | [post] access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | +| SSA.cs:105:17:105:26 | access to parameter nonTainted | SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | | SSA.cs:105:17:105:33 | access to property Length | SSA.cs:105:17:105:37 | ... > ... | | SSA.cs:106:21:106:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | | SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | +| SSA.cs:110:9:110:32 | SSA phi read(nonSink0) | SSA.cs:130:39:130:46 | access to local variable nonSink0 | +| SSA.cs:110:9:110:32 | SSA phi read(nonTainted) | SSA.cs:115:13:115:22 | access to parameter nonTainted | | SSA.cs:110:9:110:32 | SSA phi(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 | | SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) | @@ -747,15 +751,15 @@ | SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access | | SSA.cs:114:9:114:12 | this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S | -| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:114:9:114:14 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | | SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted | -| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:115:13:115:22 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:115:13:115:29 | access to property Length | SSA.cs:115:13:115:33 | ... > ... | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:119:21:119:24 | this access | | SSA.cs:117:13:117:16 | [post] this access | SSA.cs:121:21:121:24 | this access | @@ -768,21 +772,23 @@ | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | | SSA.cs:117:36:117:43 | access to local variable ssaSink0 | SSA.cs:117:13:117:43 | SSA def(this.S.SsaFieldSink1) | -| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | -| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:118:17:118:26 | [post] access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | +| SSA.cs:118:17:118:26 | access to parameter nonTainted | SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | | SSA.cs:118:17:118:33 | access to property Length | SSA.cs:118:17:118:37 | ... > ... | | SSA.cs:119:21:119:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access | | SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access | -| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S | -| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S | +| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | +| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:9:123:30 | SSA phi read(this.S) | | SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | | SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | +| SSA.cs:123:9:123:30 | SSA phi read(nonTainted) | SSA.cs:128:13:128:22 | access to parameter nonTainted | +| SSA.cs:123:9:123:30 | SSA phi read(this.S) | SSA.cs:123:23:123:28 | access to field S | | SSA.cs:123:9:123:30 | SSA phi(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | | SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access | | SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access | @@ -799,9 +805,9 @@ | SSA.cs:127:9:127:12 | this access | SSA.cs:130:13:130:16 | this access | | SSA.cs:127:9:127:12 | this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S | -| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:127:9:127:14 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | | SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted | @@ -821,16 +827,17 @@ | SSA.cs:131:17:131:33 | access to property Length | SSA.cs:131:17:131:37 | ... > ... | | SSA.cs:132:21:132:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access | | SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access | -| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S | -| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S | +| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | +| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:9:136:30 | SSA phi read(this.S) | | SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | | SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | +| SSA.cs:136:9:136:30 | SSA phi read(this.S) | SSA.cs:136:23:136:28 | access to field S | | SSA.cs:136:9:136:30 | SSA phi(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | | SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access | | SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access | @@ -859,18 +866,17 @@ | SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | | SSA.cs:171:13:171:15 | ...-- | SSA.cs:171:13:171:19 | ... > ... | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | ...-- | SSA.cs:174:20:174:26 | ... > ... | | SSA.cs:174:20:174:22 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:176:21:176:28 | [post] access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | SSA.cs:177:21:177:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | -| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | +| SSA.cs:177:21:177:28 | [post] access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | +| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:174:20:174:20 | SSA phi read(ssaSink5) | | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 | | Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted | @@ -975,3 +981,1804 @@ | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s | | Splitting.cs:58:27:58:27 | [b (line 46): false] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | +| UseUseExplosion.cs:21:10:21:10 | SSA entry def(this.Prop) | UseUseExplosion.cs:24:13:24:16 | access to property Prop | +| UseUseExplosion.cs:21:10:21:10 | this | UseUseExplosion.cs:24:13:24:16 | this access | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | +| UseUseExplosion.cs:23:13:23:17 | SSA def(x) | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:23:17:23:17 | 0 | UseUseExplosion.cs:23:13:23:17 | SSA def(x) | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | [post] this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:13:24:22 | ... > ... | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:24:31:24:34 | access to property Prop | +| UseUseExplosion.cs:24:13:24:16 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:31:24:34 | this access | +| UseUseExplosion.cs:24:13:24:16 | this access | UseUseExplosion.cs:24:3193:24:3198 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | [post] this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:31:24:39 | ... > ... | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:24:48:24:51 | access to property Prop | +| UseUseExplosion.cs:24:31:24:34 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:48:24:51 | this access | +| UseUseExplosion.cs:24:31:24:34 | this access | UseUseExplosion.cs:24:3178:24:3183 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | [post] this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:48:24:56 | ... > ... | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:24:65:24:68 | access to property Prop | +| UseUseExplosion.cs:24:48:24:51 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:65:24:68 | this access | +| UseUseExplosion.cs:24:48:24:51 | this access | UseUseExplosion.cs:24:3163:24:3168 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | [post] this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:65:24:73 | ... > ... | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:24:82:24:85 | access to property Prop | +| UseUseExplosion.cs:24:65:24:68 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:82:24:85 | this access | +| UseUseExplosion.cs:24:65:24:68 | this access | UseUseExplosion.cs:24:3148:24:3153 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | [post] this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:82:24:90 | ... > ... | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:24:99:24:102 | access to property Prop | +| UseUseExplosion.cs:24:82:24:85 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:99:24:102 | this access | +| UseUseExplosion.cs:24:82:24:85 | this access | UseUseExplosion.cs:24:3133:24:3138 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | [post] this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:99:24:107 | ... > ... | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:24:116:24:119 | access to property Prop | +| UseUseExplosion.cs:24:99:24:102 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:116:24:119 | this access | +| UseUseExplosion.cs:24:99:24:102 | this access | UseUseExplosion.cs:24:3118:24:3123 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | [post] this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:116:24:124 | ... > ... | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:24:133:24:136 | access to property Prop | +| UseUseExplosion.cs:24:116:24:119 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:133:24:136 | this access | +| UseUseExplosion.cs:24:116:24:119 | this access | UseUseExplosion.cs:24:3103:24:3108 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | [post] this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:133:24:141 | ... > ... | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:24:150:24:153 | access to property Prop | +| UseUseExplosion.cs:24:133:24:136 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:150:24:153 | this access | +| UseUseExplosion.cs:24:133:24:136 | this access | UseUseExplosion.cs:24:3088:24:3093 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | [post] this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:150:24:158 | ... > ... | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:24:167:24:170 | access to property Prop | +| UseUseExplosion.cs:24:150:24:153 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:167:24:170 | this access | +| UseUseExplosion.cs:24:150:24:153 | this access | UseUseExplosion.cs:24:3073:24:3078 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | [post] this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:167:24:175 | ... > ... | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:24:184:24:187 | access to property Prop | +| UseUseExplosion.cs:24:167:24:170 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:184:24:187 | this access | +| UseUseExplosion.cs:24:167:24:170 | this access | UseUseExplosion.cs:24:3058:24:3063 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | [post] this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:184:24:192 | ... > ... | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:24:201:24:204 | access to property Prop | +| UseUseExplosion.cs:24:184:24:187 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:201:24:204 | this access | +| UseUseExplosion.cs:24:184:24:187 | this access | UseUseExplosion.cs:24:3043:24:3048 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | [post] this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:201:24:209 | ... > ... | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:24:218:24:221 | access to property Prop | +| UseUseExplosion.cs:24:201:24:204 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:218:24:221 | this access | +| UseUseExplosion.cs:24:201:24:204 | this access | UseUseExplosion.cs:24:3028:24:3033 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | [post] this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:218:24:226 | ... > ... | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:24:235:24:238 | access to property Prop | +| UseUseExplosion.cs:24:218:24:221 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:235:24:238 | this access | +| UseUseExplosion.cs:24:218:24:221 | this access | UseUseExplosion.cs:24:3013:24:3018 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | [post] this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:235:24:243 | ... > ... | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:24:252:24:255 | access to property Prop | +| UseUseExplosion.cs:24:235:24:238 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:252:24:255 | this access | +| UseUseExplosion.cs:24:235:24:238 | this access | UseUseExplosion.cs:24:2998:24:3003 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | [post] this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:252:24:260 | ... > ... | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:24:269:24:272 | access to property Prop | +| UseUseExplosion.cs:24:252:24:255 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:269:24:272 | this access | +| UseUseExplosion.cs:24:252:24:255 | this access | UseUseExplosion.cs:24:2983:24:2988 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | [post] this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:269:24:277 | ... > ... | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:24:286:24:289 | access to property Prop | +| UseUseExplosion.cs:24:269:24:272 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:286:24:289 | this access | +| UseUseExplosion.cs:24:269:24:272 | this access | UseUseExplosion.cs:24:2968:24:2973 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | [post] this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:286:24:294 | ... > ... | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:24:303:24:306 | access to property Prop | +| UseUseExplosion.cs:24:286:24:289 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:303:24:306 | this access | +| UseUseExplosion.cs:24:286:24:289 | this access | UseUseExplosion.cs:24:2953:24:2958 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | [post] this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:303:24:311 | ... > ... | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:24:320:24:323 | access to property Prop | +| UseUseExplosion.cs:24:303:24:306 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:320:24:323 | this access | +| UseUseExplosion.cs:24:303:24:306 | this access | UseUseExplosion.cs:24:2938:24:2943 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | [post] this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:320:24:328 | ... > ... | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:24:337:24:340 | access to property Prop | +| UseUseExplosion.cs:24:320:24:323 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:337:24:340 | this access | +| UseUseExplosion.cs:24:320:24:323 | this access | UseUseExplosion.cs:24:2923:24:2928 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | [post] this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:337:24:345 | ... > ... | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:24:354:24:357 | access to property Prop | +| UseUseExplosion.cs:24:337:24:340 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:354:24:357 | this access | +| UseUseExplosion.cs:24:337:24:340 | this access | UseUseExplosion.cs:24:2908:24:2913 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | [post] this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:354:24:362 | ... > ... | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:24:371:24:374 | access to property Prop | +| UseUseExplosion.cs:24:354:24:357 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:371:24:374 | this access | +| UseUseExplosion.cs:24:354:24:357 | this access | UseUseExplosion.cs:24:2893:24:2898 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | [post] this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:371:24:379 | ... > ... | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:24:388:24:391 | access to property Prop | +| UseUseExplosion.cs:24:371:24:374 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:388:24:391 | this access | +| UseUseExplosion.cs:24:371:24:374 | this access | UseUseExplosion.cs:24:2878:24:2883 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | [post] this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:388:24:396 | ... > ... | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:24:405:24:408 | access to property Prop | +| UseUseExplosion.cs:24:388:24:391 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:405:24:408 | this access | +| UseUseExplosion.cs:24:388:24:391 | this access | UseUseExplosion.cs:24:2863:24:2868 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | [post] this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:405:24:413 | ... > ... | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:24:422:24:425 | access to property Prop | +| UseUseExplosion.cs:24:405:24:408 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:422:24:425 | this access | +| UseUseExplosion.cs:24:405:24:408 | this access | UseUseExplosion.cs:24:2848:24:2853 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | [post] this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:422:24:430 | ... > ... | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:24:439:24:442 | access to property Prop | +| UseUseExplosion.cs:24:422:24:425 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:439:24:442 | this access | +| UseUseExplosion.cs:24:422:24:425 | this access | UseUseExplosion.cs:24:2833:24:2838 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | [post] this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:439:24:447 | ... > ... | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:24:456:24:459 | access to property Prop | +| UseUseExplosion.cs:24:439:24:442 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:456:24:459 | this access | +| UseUseExplosion.cs:24:439:24:442 | this access | UseUseExplosion.cs:24:2818:24:2823 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | [post] this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:456:24:464 | ... > ... | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:24:473:24:476 | access to property Prop | +| UseUseExplosion.cs:24:456:24:459 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:473:24:476 | this access | +| UseUseExplosion.cs:24:456:24:459 | this access | UseUseExplosion.cs:24:2803:24:2808 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | [post] this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:473:24:481 | ... > ... | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:24:490:24:493 | access to property Prop | +| UseUseExplosion.cs:24:473:24:476 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:490:24:493 | this access | +| UseUseExplosion.cs:24:473:24:476 | this access | UseUseExplosion.cs:24:2788:24:2793 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | [post] this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:490:24:498 | ... > ... | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:24:507:24:510 | access to property Prop | +| UseUseExplosion.cs:24:490:24:493 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:507:24:510 | this access | +| UseUseExplosion.cs:24:490:24:493 | this access | UseUseExplosion.cs:24:2773:24:2778 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | [post] this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:507:24:515 | ... > ... | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:24:524:24:527 | access to property Prop | +| UseUseExplosion.cs:24:507:24:510 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:524:24:527 | this access | +| UseUseExplosion.cs:24:507:24:510 | this access | UseUseExplosion.cs:24:2758:24:2763 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | [post] this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:524:24:532 | ... > ... | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:24:541:24:544 | access to property Prop | +| UseUseExplosion.cs:24:524:24:527 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:541:24:544 | this access | +| UseUseExplosion.cs:24:524:24:527 | this access | UseUseExplosion.cs:24:2743:24:2748 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | [post] this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:541:24:549 | ... > ... | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:24:558:24:561 | access to property Prop | +| UseUseExplosion.cs:24:541:24:544 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:558:24:561 | this access | +| UseUseExplosion.cs:24:541:24:544 | this access | UseUseExplosion.cs:24:2728:24:2733 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | [post] this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:558:24:566 | ... > ... | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:24:575:24:578 | access to property Prop | +| UseUseExplosion.cs:24:558:24:561 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:575:24:578 | this access | +| UseUseExplosion.cs:24:558:24:561 | this access | UseUseExplosion.cs:24:2713:24:2718 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | [post] this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:575:24:583 | ... > ... | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:24:592:24:595 | access to property Prop | +| UseUseExplosion.cs:24:575:24:578 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:592:24:595 | this access | +| UseUseExplosion.cs:24:575:24:578 | this access | UseUseExplosion.cs:24:2698:24:2703 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | [post] this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:592:24:600 | ... > ... | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:24:609:24:612 | access to property Prop | +| UseUseExplosion.cs:24:592:24:595 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:609:24:612 | this access | +| UseUseExplosion.cs:24:592:24:595 | this access | UseUseExplosion.cs:24:2683:24:2688 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | [post] this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:609:24:617 | ... > ... | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:24:626:24:629 | access to property Prop | +| UseUseExplosion.cs:24:609:24:612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:626:24:629 | this access | +| UseUseExplosion.cs:24:609:24:612 | this access | UseUseExplosion.cs:24:2668:24:2673 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | [post] this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:626:24:634 | ... > ... | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:24:643:24:646 | access to property Prop | +| UseUseExplosion.cs:24:626:24:629 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:643:24:646 | this access | +| UseUseExplosion.cs:24:626:24:629 | this access | UseUseExplosion.cs:24:2653:24:2658 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | [post] this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:643:24:651 | ... > ... | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:24:660:24:663 | access to property Prop | +| UseUseExplosion.cs:24:643:24:646 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:660:24:663 | this access | +| UseUseExplosion.cs:24:643:24:646 | this access | UseUseExplosion.cs:24:2638:24:2643 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | [post] this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:660:24:668 | ... > ... | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:24:677:24:680 | access to property Prop | +| UseUseExplosion.cs:24:660:24:663 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:677:24:680 | this access | +| UseUseExplosion.cs:24:660:24:663 | this access | UseUseExplosion.cs:24:2623:24:2628 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | [post] this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:677:24:685 | ... > ... | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:24:694:24:697 | access to property Prop | +| UseUseExplosion.cs:24:677:24:680 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:694:24:697 | this access | +| UseUseExplosion.cs:24:677:24:680 | this access | UseUseExplosion.cs:24:2608:24:2613 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | [post] this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:694:24:702 | ... > ... | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:24:711:24:714 | access to property Prop | +| UseUseExplosion.cs:24:694:24:697 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:711:24:714 | this access | +| UseUseExplosion.cs:24:694:24:697 | this access | UseUseExplosion.cs:24:2593:24:2598 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | [post] this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:711:24:719 | ... > ... | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:24:728:24:731 | access to property Prop | +| UseUseExplosion.cs:24:711:24:714 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:728:24:731 | this access | +| UseUseExplosion.cs:24:711:24:714 | this access | UseUseExplosion.cs:24:2578:24:2583 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | [post] this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:728:24:736 | ... > ... | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:24:745:24:748 | access to property Prop | +| UseUseExplosion.cs:24:728:24:731 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:745:24:748 | this access | +| UseUseExplosion.cs:24:728:24:731 | this access | UseUseExplosion.cs:24:2563:24:2568 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | [post] this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:745:24:753 | ... > ... | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:24:762:24:765 | access to property Prop | +| UseUseExplosion.cs:24:745:24:748 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:762:24:765 | this access | +| UseUseExplosion.cs:24:745:24:748 | this access | UseUseExplosion.cs:24:2548:24:2553 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | [post] this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:762:24:770 | ... > ... | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:24:779:24:782 | access to property Prop | +| UseUseExplosion.cs:24:762:24:765 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:779:24:782 | this access | +| UseUseExplosion.cs:24:762:24:765 | this access | UseUseExplosion.cs:24:2533:24:2538 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | [post] this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:779:24:787 | ... > ... | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:24:796:24:799 | access to property Prop | +| UseUseExplosion.cs:24:779:24:782 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:796:24:799 | this access | +| UseUseExplosion.cs:24:779:24:782 | this access | UseUseExplosion.cs:24:2518:24:2523 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | [post] this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:796:24:804 | ... > ... | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:24:813:24:816 | access to property Prop | +| UseUseExplosion.cs:24:796:24:799 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:813:24:816 | this access | +| UseUseExplosion.cs:24:796:24:799 | this access | UseUseExplosion.cs:24:2503:24:2508 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | [post] this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:813:24:821 | ... > ... | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:24:830:24:833 | access to property Prop | +| UseUseExplosion.cs:24:813:24:816 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:830:24:833 | this access | +| UseUseExplosion.cs:24:813:24:816 | this access | UseUseExplosion.cs:24:2488:24:2493 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | [post] this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:830:24:838 | ... > ... | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:24:847:24:850 | access to property Prop | +| UseUseExplosion.cs:24:830:24:833 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:847:24:850 | this access | +| UseUseExplosion.cs:24:830:24:833 | this access | UseUseExplosion.cs:24:2473:24:2478 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | [post] this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:847:24:855 | ... > ... | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:24:864:24:867 | access to property Prop | +| UseUseExplosion.cs:24:847:24:850 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:864:24:867 | this access | +| UseUseExplosion.cs:24:847:24:850 | this access | UseUseExplosion.cs:24:2458:24:2463 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | [post] this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:864:24:872 | ... > ... | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:24:881:24:884 | access to property Prop | +| UseUseExplosion.cs:24:864:24:867 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:881:24:884 | this access | +| UseUseExplosion.cs:24:864:24:867 | this access | UseUseExplosion.cs:24:2443:24:2448 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | [post] this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:881:24:889 | ... > ... | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:24:898:24:901 | access to property Prop | +| UseUseExplosion.cs:24:881:24:884 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:898:24:901 | this access | +| UseUseExplosion.cs:24:881:24:884 | this access | UseUseExplosion.cs:24:2428:24:2433 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | [post] this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:898:24:906 | ... > ... | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:24:915:24:918 | access to property Prop | +| UseUseExplosion.cs:24:898:24:901 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:915:24:918 | this access | +| UseUseExplosion.cs:24:898:24:901 | this access | UseUseExplosion.cs:24:2413:24:2418 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | [post] this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:915:24:923 | ... > ... | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:24:932:24:935 | access to property Prop | +| UseUseExplosion.cs:24:915:24:918 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:932:24:935 | this access | +| UseUseExplosion.cs:24:915:24:918 | this access | UseUseExplosion.cs:24:2398:24:2403 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | [post] this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:932:24:940 | ... > ... | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:24:949:24:952 | access to property Prop | +| UseUseExplosion.cs:24:932:24:935 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:949:24:952 | this access | +| UseUseExplosion.cs:24:932:24:935 | this access | UseUseExplosion.cs:24:2383:24:2388 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | [post] this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:949:24:957 | ... > ... | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:24:966:24:969 | access to property Prop | +| UseUseExplosion.cs:24:949:24:952 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:966:24:969 | this access | +| UseUseExplosion.cs:24:949:24:952 | this access | UseUseExplosion.cs:24:2368:24:2373 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | [post] this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:966:24:974 | ... > ... | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:24:983:24:986 | access to property Prop | +| UseUseExplosion.cs:24:966:24:969 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:983:24:986 | this access | +| UseUseExplosion.cs:24:966:24:969 | this access | UseUseExplosion.cs:24:2353:24:2358 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | [post] this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:983:24:991 | ... > ... | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | +| UseUseExplosion.cs:24:983:24:986 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:1000:24:1003 | this access | +| UseUseExplosion.cs:24:983:24:986 | this access | UseUseExplosion.cs:24:2338:24:2343 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | [post] this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1000:24:1008 | ... > ... | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | +| UseUseExplosion.cs:24:1000:24:1003 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:1017:24:1020 | this access | +| UseUseExplosion.cs:24:1000:24:1003 | this access | UseUseExplosion.cs:24:2323:24:2328 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | [post] this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1017:24:1025 | ... > ... | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | +| UseUseExplosion.cs:24:1017:24:1020 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:1034:24:1037 | this access | +| UseUseExplosion.cs:24:1017:24:1020 | this access | UseUseExplosion.cs:24:2308:24:2313 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | [post] this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1034:24:1042 | ... > ... | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | +| UseUseExplosion.cs:24:1034:24:1037 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:1051:24:1054 | this access | +| UseUseExplosion.cs:24:1034:24:1037 | this access | UseUseExplosion.cs:24:2293:24:2298 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | [post] this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1051:24:1059 | ... > ... | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | +| UseUseExplosion.cs:24:1051:24:1054 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:1068:24:1071 | this access | +| UseUseExplosion.cs:24:1051:24:1054 | this access | UseUseExplosion.cs:24:2278:24:2283 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | [post] this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1068:24:1076 | ... > ... | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | +| UseUseExplosion.cs:24:1068:24:1071 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:1085:24:1088 | this access | +| UseUseExplosion.cs:24:1068:24:1071 | this access | UseUseExplosion.cs:24:2263:24:2268 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | [post] this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1085:24:1093 | ... > ... | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | +| UseUseExplosion.cs:24:1085:24:1088 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:1102:24:1105 | this access | +| UseUseExplosion.cs:24:1085:24:1088 | this access | UseUseExplosion.cs:24:2248:24:2253 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | [post] this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1102:24:1110 | ... > ... | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | +| UseUseExplosion.cs:24:1102:24:1105 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:1119:24:1122 | this access | +| UseUseExplosion.cs:24:1102:24:1105 | this access | UseUseExplosion.cs:24:2233:24:2238 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | [post] this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1119:24:1127 | ... > ... | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | +| UseUseExplosion.cs:24:1119:24:1122 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:1136:24:1139 | this access | +| UseUseExplosion.cs:24:1119:24:1122 | this access | UseUseExplosion.cs:24:2218:24:2223 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | [post] this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1136:24:1144 | ... > ... | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | +| UseUseExplosion.cs:24:1136:24:1139 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:1153:24:1156 | this access | +| UseUseExplosion.cs:24:1136:24:1139 | this access | UseUseExplosion.cs:24:2203:24:2208 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | [post] this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1153:24:1161 | ... > ... | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | +| UseUseExplosion.cs:24:1153:24:1156 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:1170:24:1173 | this access | +| UseUseExplosion.cs:24:1153:24:1156 | this access | UseUseExplosion.cs:24:2188:24:2193 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | [post] this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1170:24:1178 | ... > ... | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | +| UseUseExplosion.cs:24:1170:24:1173 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:1187:24:1190 | this access | +| UseUseExplosion.cs:24:1170:24:1173 | this access | UseUseExplosion.cs:24:2173:24:2178 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | [post] this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1187:24:1195 | ... > ... | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | +| UseUseExplosion.cs:24:1187:24:1190 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:1204:24:1207 | this access | +| UseUseExplosion.cs:24:1187:24:1190 | this access | UseUseExplosion.cs:24:2158:24:2163 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | [post] this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1204:24:1212 | ... > ... | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | +| UseUseExplosion.cs:24:1204:24:1207 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:1221:24:1224 | this access | +| UseUseExplosion.cs:24:1204:24:1207 | this access | UseUseExplosion.cs:24:2143:24:2148 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | [post] this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1221:24:1229 | ... > ... | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | +| UseUseExplosion.cs:24:1221:24:1224 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:1238:24:1241 | this access | +| UseUseExplosion.cs:24:1221:24:1224 | this access | UseUseExplosion.cs:24:2128:24:2133 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | [post] this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1238:24:1246 | ... > ... | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | +| UseUseExplosion.cs:24:1238:24:1241 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:1255:24:1258 | this access | +| UseUseExplosion.cs:24:1238:24:1241 | this access | UseUseExplosion.cs:24:2113:24:2118 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | [post] this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1255:24:1263 | ... > ... | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | +| UseUseExplosion.cs:24:1255:24:1258 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:1272:24:1275 | this access | +| UseUseExplosion.cs:24:1255:24:1258 | this access | UseUseExplosion.cs:24:2098:24:2103 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | [post] this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1272:24:1280 | ... > ... | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | +| UseUseExplosion.cs:24:1272:24:1275 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:1289:24:1292 | this access | +| UseUseExplosion.cs:24:1272:24:1275 | this access | UseUseExplosion.cs:24:2083:24:2088 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | [post] this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1289:24:1297 | ... > ... | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | +| UseUseExplosion.cs:24:1289:24:1292 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:1306:24:1309 | this access | +| UseUseExplosion.cs:24:1289:24:1292 | this access | UseUseExplosion.cs:24:2068:24:2073 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | [post] this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1306:24:1314 | ... > ... | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | +| UseUseExplosion.cs:24:1306:24:1309 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:1323:24:1326 | this access | +| UseUseExplosion.cs:24:1306:24:1309 | this access | UseUseExplosion.cs:24:2053:24:2058 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | [post] this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1323:24:1331 | ... > ... | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | +| UseUseExplosion.cs:24:1323:24:1326 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:1340:24:1343 | this access | +| UseUseExplosion.cs:24:1323:24:1326 | this access | UseUseExplosion.cs:24:2038:24:2043 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | [post] this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1340:24:1348 | ... > ... | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | +| UseUseExplosion.cs:24:1340:24:1343 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:1357:24:1360 | this access | +| UseUseExplosion.cs:24:1340:24:1343 | this access | UseUseExplosion.cs:24:2023:24:2028 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | [post] this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1357:24:1365 | ... > ... | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | +| UseUseExplosion.cs:24:1357:24:1360 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:1374:24:1377 | this access | +| UseUseExplosion.cs:24:1357:24:1360 | this access | UseUseExplosion.cs:24:2008:24:2013 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | [post] this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1374:24:1382 | ... > ... | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | +| UseUseExplosion.cs:24:1374:24:1377 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1391:24:1394 | this access | +| UseUseExplosion.cs:24:1374:24:1377 | this access | UseUseExplosion.cs:24:1993:24:1998 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | [post] this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1391:24:1399 | ... > ... | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | +| UseUseExplosion.cs:24:1391:24:1394 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1408:24:1411 | this access | +| UseUseExplosion.cs:24:1391:24:1394 | this access | UseUseExplosion.cs:24:1978:24:1983 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | [post] this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1408:24:1416 | ... > ... | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | +| UseUseExplosion.cs:24:1408:24:1411 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1425:24:1428 | this access | +| UseUseExplosion.cs:24:1408:24:1411 | this access | UseUseExplosion.cs:24:1963:24:1968 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | [post] this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1425:24:1433 | ... > ... | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | +| UseUseExplosion.cs:24:1425:24:1428 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1442:24:1445 | this access | +| UseUseExplosion.cs:24:1425:24:1428 | this access | UseUseExplosion.cs:24:1948:24:1953 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | [post] this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1442:24:1450 | ... > ... | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | +| UseUseExplosion.cs:24:1442:24:1445 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1459:24:1462 | this access | +| UseUseExplosion.cs:24:1442:24:1445 | this access | UseUseExplosion.cs:24:1933:24:1938 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | [post] this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1459:24:1467 | ... > ... | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | +| UseUseExplosion.cs:24:1459:24:1462 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1476:24:1479 | this access | +| UseUseExplosion.cs:24:1459:24:1462 | this access | UseUseExplosion.cs:24:1918:24:1923 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | [post] this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1476:24:1484 | ... > ... | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | +| UseUseExplosion.cs:24:1476:24:1479 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1493:24:1496 | this access | +| UseUseExplosion.cs:24:1476:24:1479 | this access | UseUseExplosion.cs:24:1903:24:1908 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | [post] this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1493:24:1501 | ... > ... | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | +| UseUseExplosion.cs:24:1493:24:1496 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1510:24:1513 | this access | +| UseUseExplosion.cs:24:1493:24:1496 | this access | UseUseExplosion.cs:24:1888:24:1893 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | [post] this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1510:24:1518 | ... > ... | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | +| UseUseExplosion.cs:24:1510:24:1513 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1527:24:1530 | this access | +| UseUseExplosion.cs:24:1510:24:1513 | this access | UseUseExplosion.cs:24:1873:24:1878 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | [post] this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1527:24:1535 | ... > ... | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | +| UseUseExplosion.cs:24:1527:24:1530 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1544:24:1547 | this access | +| UseUseExplosion.cs:24:1527:24:1530 | this access | UseUseExplosion.cs:24:1858:24:1863 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | [post] this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1544:24:1552 | ... > ... | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | +| UseUseExplosion.cs:24:1544:24:1547 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1561:24:1564 | this access | +| UseUseExplosion.cs:24:1544:24:1547 | this access | UseUseExplosion.cs:24:1843:24:1848 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | [post] this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1561:24:1568 | ... > ... | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | +| UseUseExplosion.cs:24:1561:24:1564 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1577:24:1580 | this access | +| UseUseExplosion.cs:24:1561:24:1564 | this access | UseUseExplosion.cs:24:1828:24:1833 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | [post] this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1577:24:1584 | ... > ... | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | +| UseUseExplosion.cs:24:1577:24:1580 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1593:24:1596 | this access | +| UseUseExplosion.cs:24:1577:24:1580 | this access | UseUseExplosion.cs:24:1813:24:1818 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | [post] this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1593:24:1600 | ... > ... | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | +| UseUseExplosion.cs:24:1593:24:1596 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1609:24:1612 | this access | +| UseUseExplosion.cs:24:1593:24:1596 | this access | UseUseExplosion.cs:24:1798:24:1803 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | [post] this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1609:24:1616 | ... > ... | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | +| UseUseExplosion.cs:24:1609:24:1612 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1625:24:1628 | this access | +| UseUseExplosion.cs:24:1609:24:1612 | this access | UseUseExplosion.cs:24:1783:24:1788 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | [post] this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1625:24:1632 | ... > ... | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | +| UseUseExplosion.cs:24:1625:24:1628 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1641:24:1644 | this access | +| UseUseExplosion.cs:24:1625:24:1628 | this access | UseUseExplosion.cs:24:1768:24:1773 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | [post] this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1641:24:1648 | ... > ... | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | +| UseUseExplosion.cs:24:1641:24:1644 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1657:24:1660 | this access | +| UseUseExplosion.cs:24:1641:24:1644 | this access | UseUseExplosion.cs:24:1753:24:1758 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | [post] this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1657:24:1664 | ... > ... | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | +| UseUseExplosion.cs:24:1657:24:1660 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1673:24:1676 | this access | +| UseUseExplosion.cs:24:1657:24:1660 | this access | UseUseExplosion.cs:24:1738:24:1743 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | [post] this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1673:24:1680 | ... > ... | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | +| UseUseExplosion.cs:24:1673:24:1676 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1689:24:1692 | this access | +| UseUseExplosion.cs:24:1673:24:1676 | this access | UseUseExplosion.cs:24:1723:24:1728 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:24:1689:24:1696 | ... > ... | +| UseUseExplosion.cs:24:1689:24:1692 | access to property Prop | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:24:1708:24:1713 | this access | +| UseUseExplosion.cs:24:1689:24:1692 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1708:24:1713 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1712:24:1712 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1723:24:1728 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1723:24:1728 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1727:24:1727 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1738:24:1743 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1738:24:1743 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1742:24:1742 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1753:24:1758 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1753:24:1758 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1757:24:1757 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1768:24:1773 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1768:24:1773 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1772:24:1772 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1783:24:1788 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1783:24:1788 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1787:24:1787 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1798:24:1803 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1798:24:1803 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1802:24:1802 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1813:24:1818 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1813:24:1818 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1817:24:1817 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1828:24:1833 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1828:24:1833 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1832:24:1832 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1843:24:1848 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1843:24:1848 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1847:24:1847 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1858:24:1863 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1858:24:1863 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1862:24:1862 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1873:24:1878 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1873:24:1878 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1877:24:1877 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1888:24:1893 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1888:24:1893 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1892:24:1892 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1903:24:1908 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1903:24:1908 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1907:24:1907 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1918:24:1923 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1918:24:1923 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1922:24:1922 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1933:24:1938 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1933:24:1938 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1937:24:1937 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1948:24:1953 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1948:24:1953 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1952:24:1952 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1963:24:1968 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1963:24:1968 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1967:24:1967 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1978:24:1983 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1978:24:1983 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1982:24:1982 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:1993:24:1998 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1993:24:1998 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:1997:24:1997 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2008:24:2013 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2008:24:2013 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2012:24:2012 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2023:24:2028 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2023:24:2028 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2027:24:2027 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2038:24:2043 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2038:24:2043 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2042:24:2042 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2053:24:2058 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2053:24:2058 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2057:24:2057 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2068:24:2073 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2068:24:2073 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2072:24:2072 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2083:24:2088 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2083:24:2088 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2087:24:2087 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2098:24:2103 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2098:24:2103 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2102:24:2102 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2113:24:2118 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2113:24:2118 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2117:24:2117 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2128:24:2133 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2128:24:2133 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2132:24:2132 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2143:24:2148 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2143:24:2148 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2147:24:2147 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2158:24:2163 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2158:24:2163 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2162:24:2162 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2173:24:2178 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2173:24:2178 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2177:24:2177 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2188:24:2193 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2188:24:2193 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2192:24:2192 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2203:24:2208 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2203:24:2208 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2207:24:2207 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2218:24:2223 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2218:24:2223 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2222:24:2222 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2233:24:2238 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2233:24:2238 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2237:24:2237 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2248:24:2253 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2248:24:2253 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2252:24:2252 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2263:24:2268 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2263:24:2268 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2267:24:2267 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2278:24:2283 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2278:24:2283 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2282:24:2282 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2293:24:2298 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2293:24:2298 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2297:24:2297 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2308:24:2313 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2308:24:2313 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2312:24:2312 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2323:24:2328 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2323:24:2328 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2327:24:2327 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2338:24:2343 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2338:24:2343 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2342:24:2342 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2353:24:2358 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2353:24:2358 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2357:24:2357 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2368:24:2373 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2368:24:2373 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2372:24:2372 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2383:24:2388 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2383:24:2388 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2387:24:2387 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2398:24:2403 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2398:24:2403 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2402:24:2402 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2413:24:2418 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2413:24:2418 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2417:24:2417 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2428:24:2433 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2428:24:2433 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2432:24:2432 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2443:24:2448 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2443:24:2448 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2447:24:2447 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2458:24:2463 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2458:24:2463 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2462:24:2462 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2473:24:2478 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2473:24:2478 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2477:24:2477 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2488:24:2493 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2488:24:2493 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2492:24:2492 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2503:24:2508 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2503:24:2508 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2507:24:2507 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2518:24:2523 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2518:24:2523 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2522:24:2522 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2533:24:2538 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2533:24:2538 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2537:24:2537 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2548:24:2553 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2548:24:2553 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2552:24:2552 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2563:24:2568 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2563:24:2568 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2567:24:2567 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2578:24:2583 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2578:24:2583 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2582:24:2582 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2593:24:2598 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2593:24:2598 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2597:24:2597 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2608:24:2613 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2608:24:2613 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2612:24:2612 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2623:24:2628 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2623:24:2628 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2627:24:2627 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2638:24:2643 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2638:24:2643 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2642:24:2642 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2653:24:2658 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2653:24:2658 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2657:24:2657 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2668:24:2673 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2668:24:2673 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2672:24:2672 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2683:24:2688 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2683:24:2688 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2687:24:2687 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2698:24:2703 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2698:24:2703 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2702:24:2702 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2713:24:2718 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2713:24:2718 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2717:24:2717 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2728:24:2733 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2728:24:2733 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2732:24:2732 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2743:24:2748 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2743:24:2748 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2747:24:2747 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2758:24:2763 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2758:24:2763 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2762:24:2762 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2773:24:2778 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2773:24:2778 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2777:24:2777 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2788:24:2793 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2788:24:2793 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2792:24:2792 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2803:24:2808 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2803:24:2808 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2807:24:2807 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2818:24:2823 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2818:24:2823 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2822:24:2822 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2833:24:2838 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2833:24:2838 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2837:24:2837 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2848:24:2853 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2848:24:2853 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2852:24:2852 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2863:24:2868 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2863:24:2868 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2867:24:2867 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2878:24:2883 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2878:24:2883 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2882:24:2882 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2893:24:2898 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2893:24:2898 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2897:24:2897 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2908:24:2913 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2908:24:2913 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2912:24:2912 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2923:24:2928 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2923:24:2928 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2927:24:2927 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2938:24:2943 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2938:24:2943 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2942:24:2942 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2953:24:2958 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2953:24:2958 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2957:24:2957 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2968:24:2973 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2968:24:2973 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2972:24:2972 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2983:24:2988 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2983:24:2988 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2987:24:2987 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:2998:24:3003 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:2998:24:3003 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3002:24:3002 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3013:24:3018 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3013:24:3018 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3017:24:3017 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3028:24:3033 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3028:24:3033 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3032:24:3032 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3043:24:3048 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3043:24:3048 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3047:24:3047 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3058:24:3063 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3058:24:3063 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3062:24:3062 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3073:24:3078 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3073:24:3078 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3077:24:3077 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3088:24:3093 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3088:24:3093 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3092:24:3092 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3103:24:3108 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3103:24:3108 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3107:24:3107 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3118:24:3123 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3118:24:3123 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3122:24:3122 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3133:24:3138 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3133:24:3138 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3137:24:3137 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3148:24:3153 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3148:24:3153 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3152:24:3152 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3163:24:3168 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3163:24:3168 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3167:24:3167 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3178:24:3183 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3178:24:3183 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3182:24:3182 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:24:3193:24:3198 | [post] this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3193:24:3198 | this access | UseUseExplosion.cs:25:13:25:16 | this access | +| UseUseExplosion.cs:24:3197:24:3197 | access to local variable x | UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(this.Prop) | UseUseExplosion.cs:25:13:25:16 | access to property Prop | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1712:25:1712 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1727:25:1727 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1742:25:1742 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1757:25:1757 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1772:25:1772 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1787:25:1787 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1802:25:1802 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1817:25:1817 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1832:25:1832 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1847:25:1847 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1862:25:1862 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1877:25:1877 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1892:25:1892 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1907:25:1907 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1922:25:1922 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1937:25:1937 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1952:25:1952 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1967:25:1967 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1982:25:1982 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:1997:25:1997 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2012:25:2012 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2027:25:2027 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2042:25:2042 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2057:25:2057 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2072:25:2072 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2087:25:2087 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2102:25:2102 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2117:25:2117 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2132:25:2132 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2147:25:2147 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2162:25:2162 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2177:25:2177 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2192:25:2192 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2207:25:2207 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2222:25:2222 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2237:25:2237 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2252:25:2252 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2267:25:2267 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2282:25:2282 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2297:25:2297 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2312:25:2312 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2327:25:2327 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2342:25:2342 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2357:25:2357 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2372:25:2372 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2387:25:2387 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2402:25:2402 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2417:25:2417 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2432:25:2432 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2447:25:2447 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2462:25:2462 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2477:25:2477 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2492:25:2492 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2507:25:2507 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2522:25:2522 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2537:25:2537 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2552:25:2552 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2567:25:2567 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2582:25:2582 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2597:25:2597 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2612:25:2612 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2627:25:2627 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2642:25:2642 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2657:25:2657 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2672:25:2672 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2687:25:2687 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2702:25:2702 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2717:25:2717 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2732:25:2732 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2747:25:2747 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2762:25:2762 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2777:25:2777 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2792:25:2792 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2807:25:2807 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2822:25:2822 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2837:25:2837 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2852:25:2852 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2867:25:2867 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2882:25:2882 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2897:25:2897 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2912:25:2912 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2927:25:2927 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2942:25:2942 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2957:25:2957 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2972:25:2972 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:2987:25:2987 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3002:25:3002 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3017:25:3017 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3032:25:3032 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3047:25:3047 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3062:25:3062 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3077:25:3077 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3092:25:3092 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3107:25:3107 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3122:25:3122 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3137:25:3137 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3152:25:3152 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3167:25:3167 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3182:25:3182 | access to local variable x | +| UseUseExplosion.cs:25:9:25:3199 | SSA phi read(x) | UseUseExplosion.cs:25:3197:25:3197 | access to local variable x | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | [post] this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:13:25:22 | ... > ... | +| UseUseExplosion.cs:25:13:25:16 | access to property Prop | UseUseExplosion.cs:25:31:25:34 | access to property Prop | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:31:25:34 | this access | +| UseUseExplosion.cs:25:13:25:16 | this access | UseUseExplosion.cs:25:3193:25:3198 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | [post] this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:31:25:39 | ... > ... | +| UseUseExplosion.cs:25:31:25:34 | access to property Prop | UseUseExplosion.cs:25:48:25:51 | access to property Prop | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:48:25:51 | this access | +| UseUseExplosion.cs:25:31:25:34 | this access | UseUseExplosion.cs:25:3178:25:3183 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | [post] this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:48:25:56 | ... > ... | +| UseUseExplosion.cs:25:48:25:51 | access to property Prop | UseUseExplosion.cs:25:65:25:68 | access to property Prop | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:65:25:68 | this access | +| UseUseExplosion.cs:25:48:25:51 | this access | UseUseExplosion.cs:25:3163:25:3168 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | [post] this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:65:25:73 | ... > ... | +| UseUseExplosion.cs:25:65:25:68 | access to property Prop | UseUseExplosion.cs:25:82:25:85 | access to property Prop | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:82:25:85 | this access | +| UseUseExplosion.cs:25:65:25:68 | this access | UseUseExplosion.cs:25:3148:25:3153 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | [post] this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:82:25:90 | ... > ... | +| UseUseExplosion.cs:25:82:25:85 | access to property Prop | UseUseExplosion.cs:25:99:25:102 | access to property Prop | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:99:25:102 | this access | +| UseUseExplosion.cs:25:82:25:85 | this access | UseUseExplosion.cs:25:3133:25:3138 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | [post] this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:99:25:107 | ... > ... | +| UseUseExplosion.cs:25:99:25:102 | access to property Prop | UseUseExplosion.cs:25:116:25:119 | access to property Prop | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:116:25:119 | this access | +| UseUseExplosion.cs:25:99:25:102 | this access | UseUseExplosion.cs:25:3118:25:3123 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | [post] this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:116:25:124 | ... > ... | +| UseUseExplosion.cs:25:116:25:119 | access to property Prop | UseUseExplosion.cs:25:133:25:136 | access to property Prop | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:133:25:136 | this access | +| UseUseExplosion.cs:25:116:25:119 | this access | UseUseExplosion.cs:25:3103:25:3108 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | [post] this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:133:25:141 | ... > ... | +| UseUseExplosion.cs:25:133:25:136 | access to property Prop | UseUseExplosion.cs:25:150:25:153 | access to property Prop | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:150:25:153 | this access | +| UseUseExplosion.cs:25:133:25:136 | this access | UseUseExplosion.cs:25:3088:25:3093 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | [post] this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:150:25:158 | ... > ... | +| UseUseExplosion.cs:25:150:25:153 | access to property Prop | UseUseExplosion.cs:25:167:25:170 | access to property Prop | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:167:25:170 | this access | +| UseUseExplosion.cs:25:150:25:153 | this access | UseUseExplosion.cs:25:3073:25:3078 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | [post] this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:167:25:175 | ... > ... | +| UseUseExplosion.cs:25:167:25:170 | access to property Prop | UseUseExplosion.cs:25:184:25:187 | access to property Prop | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:184:25:187 | this access | +| UseUseExplosion.cs:25:167:25:170 | this access | UseUseExplosion.cs:25:3058:25:3063 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | [post] this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:184:25:192 | ... > ... | +| UseUseExplosion.cs:25:184:25:187 | access to property Prop | UseUseExplosion.cs:25:201:25:204 | access to property Prop | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:201:25:204 | this access | +| UseUseExplosion.cs:25:184:25:187 | this access | UseUseExplosion.cs:25:3043:25:3048 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | [post] this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:201:25:209 | ... > ... | +| UseUseExplosion.cs:25:201:25:204 | access to property Prop | UseUseExplosion.cs:25:218:25:221 | access to property Prop | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:218:25:221 | this access | +| UseUseExplosion.cs:25:201:25:204 | this access | UseUseExplosion.cs:25:3028:25:3033 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | [post] this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:218:25:226 | ... > ... | +| UseUseExplosion.cs:25:218:25:221 | access to property Prop | UseUseExplosion.cs:25:235:25:238 | access to property Prop | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:235:25:238 | this access | +| UseUseExplosion.cs:25:218:25:221 | this access | UseUseExplosion.cs:25:3013:25:3018 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | [post] this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:235:25:243 | ... > ... | +| UseUseExplosion.cs:25:235:25:238 | access to property Prop | UseUseExplosion.cs:25:252:25:255 | access to property Prop | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:252:25:255 | this access | +| UseUseExplosion.cs:25:235:25:238 | this access | UseUseExplosion.cs:25:2998:25:3003 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | [post] this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:252:25:260 | ... > ... | +| UseUseExplosion.cs:25:252:25:255 | access to property Prop | UseUseExplosion.cs:25:269:25:272 | access to property Prop | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:269:25:272 | this access | +| UseUseExplosion.cs:25:252:25:255 | this access | UseUseExplosion.cs:25:2983:25:2988 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | [post] this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:269:25:277 | ... > ... | +| UseUseExplosion.cs:25:269:25:272 | access to property Prop | UseUseExplosion.cs:25:286:25:289 | access to property Prop | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:286:25:289 | this access | +| UseUseExplosion.cs:25:269:25:272 | this access | UseUseExplosion.cs:25:2968:25:2973 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | [post] this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:286:25:294 | ... > ... | +| UseUseExplosion.cs:25:286:25:289 | access to property Prop | UseUseExplosion.cs:25:303:25:306 | access to property Prop | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:303:25:306 | this access | +| UseUseExplosion.cs:25:286:25:289 | this access | UseUseExplosion.cs:25:2953:25:2958 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | [post] this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:303:25:311 | ... > ... | +| UseUseExplosion.cs:25:303:25:306 | access to property Prop | UseUseExplosion.cs:25:320:25:323 | access to property Prop | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:320:25:323 | this access | +| UseUseExplosion.cs:25:303:25:306 | this access | UseUseExplosion.cs:25:2938:25:2943 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | [post] this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:320:25:328 | ... > ... | +| UseUseExplosion.cs:25:320:25:323 | access to property Prop | UseUseExplosion.cs:25:337:25:340 | access to property Prop | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:337:25:340 | this access | +| UseUseExplosion.cs:25:320:25:323 | this access | UseUseExplosion.cs:25:2923:25:2928 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | [post] this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:337:25:345 | ... > ... | +| UseUseExplosion.cs:25:337:25:340 | access to property Prop | UseUseExplosion.cs:25:354:25:357 | access to property Prop | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:354:25:357 | this access | +| UseUseExplosion.cs:25:337:25:340 | this access | UseUseExplosion.cs:25:2908:25:2913 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | [post] this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:354:25:362 | ... > ... | +| UseUseExplosion.cs:25:354:25:357 | access to property Prop | UseUseExplosion.cs:25:371:25:374 | access to property Prop | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:371:25:374 | this access | +| UseUseExplosion.cs:25:354:25:357 | this access | UseUseExplosion.cs:25:2893:25:2898 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | [post] this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:371:25:379 | ... > ... | +| UseUseExplosion.cs:25:371:25:374 | access to property Prop | UseUseExplosion.cs:25:388:25:391 | access to property Prop | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:388:25:391 | this access | +| UseUseExplosion.cs:25:371:25:374 | this access | UseUseExplosion.cs:25:2878:25:2883 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | [post] this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:388:25:396 | ... > ... | +| UseUseExplosion.cs:25:388:25:391 | access to property Prop | UseUseExplosion.cs:25:405:25:408 | access to property Prop | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:405:25:408 | this access | +| UseUseExplosion.cs:25:388:25:391 | this access | UseUseExplosion.cs:25:2863:25:2868 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | [post] this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:405:25:413 | ... > ... | +| UseUseExplosion.cs:25:405:25:408 | access to property Prop | UseUseExplosion.cs:25:422:25:425 | access to property Prop | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:422:25:425 | this access | +| UseUseExplosion.cs:25:405:25:408 | this access | UseUseExplosion.cs:25:2848:25:2853 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | [post] this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:422:25:430 | ... > ... | +| UseUseExplosion.cs:25:422:25:425 | access to property Prop | UseUseExplosion.cs:25:439:25:442 | access to property Prop | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:439:25:442 | this access | +| UseUseExplosion.cs:25:422:25:425 | this access | UseUseExplosion.cs:25:2833:25:2838 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | [post] this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:439:25:447 | ... > ... | +| UseUseExplosion.cs:25:439:25:442 | access to property Prop | UseUseExplosion.cs:25:456:25:459 | access to property Prop | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:456:25:459 | this access | +| UseUseExplosion.cs:25:439:25:442 | this access | UseUseExplosion.cs:25:2818:25:2823 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | [post] this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:456:25:464 | ... > ... | +| UseUseExplosion.cs:25:456:25:459 | access to property Prop | UseUseExplosion.cs:25:473:25:476 | access to property Prop | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:473:25:476 | this access | +| UseUseExplosion.cs:25:456:25:459 | this access | UseUseExplosion.cs:25:2803:25:2808 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | [post] this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:473:25:481 | ... > ... | +| UseUseExplosion.cs:25:473:25:476 | access to property Prop | UseUseExplosion.cs:25:490:25:493 | access to property Prop | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:490:25:493 | this access | +| UseUseExplosion.cs:25:473:25:476 | this access | UseUseExplosion.cs:25:2788:25:2793 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | [post] this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:490:25:498 | ... > ... | +| UseUseExplosion.cs:25:490:25:493 | access to property Prop | UseUseExplosion.cs:25:507:25:510 | access to property Prop | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:507:25:510 | this access | +| UseUseExplosion.cs:25:490:25:493 | this access | UseUseExplosion.cs:25:2773:25:2778 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | [post] this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:507:25:515 | ... > ... | +| UseUseExplosion.cs:25:507:25:510 | access to property Prop | UseUseExplosion.cs:25:524:25:527 | access to property Prop | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:524:25:527 | this access | +| UseUseExplosion.cs:25:507:25:510 | this access | UseUseExplosion.cs:25:2758:25:2763 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | [post] this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:524:25:532 | ... > ... | +| UseUseExplosion.cs:25:524:25:527 | access to property Prop | UseUseExplosion.cs:25:541:25:544 | access to property Prop | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:541:25:544 | this access | +| UseUseExplosion.cs:25:524:25:527 | this access | UseUseExplosion.cs:25:2743:25:2748 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | [post] this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:541:25:549 | ... > ... | +| UseUseExplosion.cs:25:541:25:544 | access to property Prop | UseUseExplosion.cs:25:558:25:561 | access to property Prop | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:558:25:561 | this access | +| UseUseExplosion.cs:25:541:25:544 | this access | UseUseExplosion.cs:25:2728:25:2733 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | [post] this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:558:25:566 | ... > ... | +| UseUseExplosion.cs:25:558:25:561 | access to property Prop | UseUseExplosion.cs:25:575:25:578 | access to property Prop | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:575:25:578 | this access | +| UseUseExplosion.cs:25:558:25:561 | this access | UseUseExplosion.cs:25:2713:25:2718 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | [post] this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:575:25:583 | ... > ... | +| UseUseExplosion.cs:25:575:25:578 | access to property Prop | UseUseExplosion.cs:25:592:25:595 | access to property Prop | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:592:25:595 | this access | +| UseUseExplosion.cs:25:575:25:578 | this access | UseUseExplosion.cs:25:2698:25:2703 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | [post] this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:592:25:600 | ... > ... | +| UseUseExplosion.cs:25:592:25:595 | access to property Prop | UseUseExplosion.cs:25:609:25:612 | access to property Prop | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:609:25:612 | this access | +| UseUseExplosion.cs:25:592:25:595 | this access | UseUseExplosion.cs:25:2683:25:2688 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | [post] this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:609:25:617 | ... > ... | +| UseUseExplosion.cs:25:609:25:612 | access to property Prop | UseUseExplosion.cs:25:626:25:629 | access to property Prop | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:626:25:629 | this access | +| UseUseExplosion.cs:25:609:25:612 | this access | UseUseExplosion.cs:25:2668:25:2673 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | [post] this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:626:25:634 | ... > ... | +| UseUseExplosion.cs:25:626:25:629 | access to property Prop | UseUseExplosion.cs:25:643:25:646 | access to property Prop | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:643:25:646 | this access | +| UseUseExplosion.cs:25:626:25:629 | this access | UseUseExplosion.cs:25:2653:25:2658 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | [post] this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:643:25:651 | ... > ... | +| UseUseExplosion.cs:25:643:25:646 | access to property Prop | UseUseExplosion.cs:25:660:25:663 | access to property Prop | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:660:25:663 | this access | +| UseUseExplosion.cs:25:643:25:646 | this access | UseUseExplosion.cs:25:2638:25:2643 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | [post] this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:660:25:668 | ... > ... | +| UseUseExplosion.cs:25:660:25:663 | access to property Prop | UseUseExplosion.cs:25:677:25:680 | access to property Prop | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:677:25:680 | this access | +| UseUseExplosion.cs:25:660:25:663 | this access | UseUseExplosion.cs:25:2623:25:2628 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | [post] this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:677:25:685 | ... > ... | +| UseUseExplosion.cs:25:677:25:680 | access to property Prop | UseUseExplosion.cs:25:694:25:697 | access to property Prop | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:694:25:697 | this access | +| UseUseExplosion.cs:25:677:25:680 | this access | UseUseExplosion.cs:25:2608:25:2613 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | [post] this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:694:25:702 | ... > ... | +| UseUseExplosion.cs:25:694:25:697 | access to property Prop | UseUseExplosion.cs:25:711:25:714 | access to property Prop | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:711:25:714 | this access | +| UseUseExplosion.cs:25:694:25:697 | this access | UseUseExplosion.cs:25:2593:25:2598 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | [post] this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:711:25:719 | ... > ... | +| UseUseExplosion.cs:25:711:25:714 | access to property Prop | UseUseExplosion.cs:25:728:25:731 | access to property Prop | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:728:25:731 | this access | +| UseUseExplosion.cs:25:711:25:714 | this access | UseUseExplosion.cs:25:2578:25:2583 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | [post] this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:728:25:736 | ... > ... | +| UseUseExplosion.cs:25:728:25:731 | access to property Prop | UseUseExplosion.cs:25:745:25:748 | access to property Prop | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:745:25:748 | this access | +| UseUseExplosion.cs:25:728:25:731 | this access | UseUseExplosion.cs:25:2563:25:2568 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | [post] this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:745:25:753 | ... > ... | +| UseUseExplosion.cs:25:745:25:748 | access to property Prop | UseUseExplosion.cs:25:762:25:765 | access to property Prop | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:762:25:765 | this access | +| UseUseExplosion.cs:25:745:25:748 | this access | UseUseExplosion.cs:25:2548:25:2553 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | [post] this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:762:25:770 | ... > ... | +| UseUseExplosion.cs:25:762:25:765 | access to property Prop | UseUseExplosion.cs:25:779:25:782 | access to property Prop | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:779:25:782 | this access | +| UseUseExplosion.cs:25:762:25:765 | this access | UseUseExplosion.cs:25:2533:25:2538 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | [post] this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:779:25:787 | ... > ... | +| UseUseExplosion.cs:25:779:25:782 | access to property Prop | UseUseExplosion.cs:25:796:25:799 | access to property Prop | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:796:25:799 | this access | +| UseUseExplosion.cs:25:779:25:782 | this access | UseUseExplosion.cs:25:2518:25:2523 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | [post] this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:796:25:804 | ... > ... | +| UseUseExplosion.cs:25:796:25:799 | access to property Prop | UseUseExplosion.cs:25:813:25:816 | access to property Prop | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:813:25:816 | this access | +| UseUseExplosion.cs:25:796:25:799 | this access | UseUseExplosion.cs:25:2503:25:2508 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | [post] this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:813:25:821 | ... > ... | +| UseUseExplosion.cs:25:813:25:816 | access to property Prop | UseUseExplosion.cs:25:830:25:833 | access to property Prop | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:830:25:833 | this access | +| UseUseExplosion.cs:25:813:25:816 | this access | UseUseExplosion.cs:25:2488:25:2493 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | [post] this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:830:25:838 | ... > ... | +| UseUseExplosion.cs:25:830:25:833 | access to property Prop | UseUseExplosion.cs:25:847:25:850 | access to property Prop | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:847:25:850 | this access | +| UseUseExplosion.cs:25:830:25:833 | this access | UseUseExplosion.cs:25:2473:25:2478 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | [post] this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:847:25:855 | ... > ... | +| UseUseExplosion.cs:25:847:25:850 | access to property Prop | UseUseExplosion.cs:25:864:25:867 | access to property Prop | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:864:25:867 | this access | +| UseUseExplosion.cs:25:847:25:850 | this access | UseUseExplosion.cs:25:2458:25:2463 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | [post] this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:864:25:872 | ... > ... | +| UseUseExplosion.cs:25:864:25:867 | access to property Prop | UseUseExplosion.cs:25:881:25:884 | access to property Prop | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:881:25:884 | this access | +| UseUseExplosion.cs:25:864:25:867 | this access | UseUseExplosion.cs:25:2443:25:2448 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | [post] this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:881:25:889 | ... > ... | +| UseUseExplosion.cs:25:881:25:884 | access to property Prop | UseUseExplosion.cs:25:898:25:901 | access to property Prop | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:898:25:901 | this access | +| UseUseExplosion.cs:25:881:25:884 | this access | UseUseExplosion.cs:25:2428:25:2433 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | [post] this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:898:25:906 | ... > ... | +| UseUseExplosion.cs:25:898:25:901 | access to property Prop | UseUseExplosion.cs:25:915:25:918 | access to property Prop | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:915:25:918 | this access | +| UseUseExplosion.cs:25:898:25:901 | this access | UseUseExplosion.cs:25:2413:25:2418 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | [post] this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:915:25:923 | ... > ... | +| UseUseExplosion.cs:25:915:25:918 | access to property Prop | UseUseExplosion.cs:25:932:25:935 | access to property Prop | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:932:25:935 | this access | +| UseUseExplosion.cs:25:915:25:918 | this access | UseUseExplosion.cs:25:2398:25:2403 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | [post] this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:932:25:940 | ... > ... | +| UseUseExplosion.cs:25:932:25:935 | access to property Prop | UseUseExplosion.cs:25:949:25:952 | access to property Prop | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:949:25:952 | this access | +| UseUseExplosion.cs:25:932:25:935 | this access | UseUseExplosion.cs:25:2383:25:2388 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | [post] this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:949:25:957 | ... > ... | +| UseUseExplosion.cs:25:949:25:952 | access to property Prop | UseUseExplosion.cs:25:966:25:969 | access to property Prop | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:966:25:969 | this access | +| UseUseExplosion.cs:25:949:25:952 | this access | UseUseExplosion.cs:25:2368:25:2373 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | [post] this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:966:25:974 | ... > ... | +| UseUseExplosion.cs:25:966:25:969 | access to property Prop | UseUseExplosion.cs:25:983:25:986 | access to property Prop | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:983:25:986 | this access | +| UseUseExplosion.cs:25:966:25:969 | this access | UseUseExplosion.cs:25:2353:25:2358 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | [post] this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:983:25:991 | ... > ... | +| UseUseExplosion.cs:25:983:25:986 | access to property Prop | UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:1000:25:1003 | this access | +| UseUseExplosion.cs:25:983:25:986 | this access | UseUseExplosion.cs:25:2338:25:2343 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | [post] this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1000:25:1008 | ... > ... | +| UseUseExplosion.cs:25:1000:25:1003 | access to property Prop | UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:1017:25:1020 | this access | +| UseUseExplosion.cs:25:1000:25:1003 | this access | UseUseExplosion.cs:25:2323:25:2328 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | [post] this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1017:25:1025 | ... > ... | +| UseUseExplosion.cs:25:1017:25:1020 | access to property Prop | UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:1034:25:1037 | this access | +| UseUseExplosion.cs:25:1017:25:1020 | this access | UseUseExplosion.cs:25:2308:25:2313 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | [post] this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1034:25:1042 | ... > ... | +| UseUseExplosion.cs:25:1034:25:1037 | access to property Prop | UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:1051:25:1054 | this access | +| UseUseExplosion.cs:25:1034:25:1037 | this access | UseUseExplosion.cs:25:2293:25:2298 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | [post] this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1051:25:1059 | ... > ... | +| UseUseExplosion.cs:25:1051:25:1054 | access to property Prop | UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:1068:25:1071 | this access | +| UseUseExplosion.cs:25:1051:25:1054 | this access | UseUseExplosion.cs:25:2278:25:2283 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | [post] this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1068:25:1076 | ... > ... | +| UseUseExplosion.cs:25:1068:25:1071 | access to property Prop | UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:1085:25:1088 | this access | +| UseUseExplosion.cs:25:1068:25:1071 | this access | UseUseExplosion.cs:25:2263:25:2268 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | [post] this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1085:25:1093 | ... > ... | +| UseUseExplosion.cs:25:1085:25:1088 | access to property Prop | UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:1102:25:1105 | this access | +| UseUseExplosion.cs:25:1085:25:1088 | this access | UseUseExplosion.cs:25:2248:25:2253 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | [post] this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1102:25:1110 | ... > ... | +| UseUseExplosion.cs:25:1102:25:1105 | access to property Prop | UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:1119:25:1122 | this access | +| UseUseExplosion.cs:25:1102:25:1105 | this access | UseUseExplosion.cs:25:2233:25:2238 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | [post] this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1119:25:1127 | ... > ... | +| UseUseExplosion.cs:25:1119:25:1122 | access to property Prop | UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:1136:25:1139 | this access | +| UseUseExplosion.cs:25:1119:25:1122 | this access | UseUseExplosion.cs:25:2218:25:2223 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | [post] this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1136:25:1144 | ... > ... | +| UseUseExplosion.cs:25:1136:25:1139 | access to property Prop | UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:1153:25:1156 | this access | +| UseUseExplosion.cs:25:1136:25:1139 | this access | UseUseExplosion.cs:25:2203:25:2208 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | [post] this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1153:25:1161 | ... > ... | +| UseUseExplosion.cs:25:1153:25:1156 | access to property Prop | UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:1170:25:1173 | this access | +| UseUseExplosion.cs:25:1153:25:1156 | this access | UseUseExplosion.cs:25:2188:25:2193 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | [post] this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1170:25:1178 | ... > ... | +| UseUseExplosion.cs:25:1170:25:1173 | access to property Prop | UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:1187:25:1190 | this access | +| UseUseExplosion.cs:25:1170:25:1173 | this access | UseUseExplosion.cs:25:2173:25:2178 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | [post] this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1187:25:1195 | ... > ... | +| UseUseExplosion.cs:25:1187:25:1190 | access to property Prop | UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:1204:25:1207 | this access | +| UseUseExplosion.cs:25:1187:25:1190 | this access | UseUseExplosion.cs:25:2158:25:2163 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | [post] this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1204:25:1212 | ... > ... | +| UseUseExplosion.cs:25:1204:25:1207 | access to property Prop | UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:1221:25:1224 | this access | +| UseUseExplosion.cs:25:1204:25:1207 | this access | UseUseExplosion.cs:25:2143:25:2148 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | [post] this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1221:25:1229 | ... > ... | +| UseUseExplosion.cs:25:1221:25:1224 | access to property Prop | UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:1238:25:1241 | this access | +| UseUseExplosion.cs:25:1221:25:1224 | this access | UseUseExplosion.cs:25:2128:25:2133 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | [post] this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1238:25:1246 | ... > ... | +| UseUseExplosion.cs:25:1238:25:1241 | access to property Prop | UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:1255:25:1258 | this access | +| UseUseExplosion.cs:25:1238:25:1241 | this access | UseUseExplosion.cs:25:2113:25:2118 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | [post] this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1255:25:1263 | ... > ... | +| UseUseExplosion.cs:25:1255:25:1258 | access to property Prop | UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:1272:25:1275 | this access | +| UseUseExplosion.cs:25:1255:25:1258 | this access | UseUseExplosion.cs:25:2098:25:2103 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | [post] this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1272:25:1280 | ... > ... | +| UseUseExplosion.cs:25:1272:25:1275 | access to property Prop | UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:1289:25:1292 | this access | +| UseUseExplosion.cs:25:1272:25:1275 | this access | UseUseExplosion.cs:25:2083:25:2088 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | [post] this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1289:25:1297 | ... > ... | +| UseUseExplosion.cs:25:1289:25:1292 | access to property Prop | UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:1306:25:1309 | this access | +| UseUseExplosion.cs:25:1289:25:1292 | this access | UseUseExplosion.cs:25:2068:25:2073 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | [post] this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1306:25:1314 | ... > ... | +| UseUseExplosion.cs:25:1306:25:1309 | access to property Prop | UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:1323:25:1326 | this access | +| UseUseExplosion.cs:25:1306:25:1309 | this access | UseUseExplosion.cs:25:2053:25:2058 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | [post] this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1323:25:1331 | ... > ... | +| UseUseExplosion.cs:25:1323:25:1326 | access to property Prop | UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:1340:25:1343 | this access | +| UseUseExplosion.cs:25:1323:25:1326 | this access | UseUseExplosion.cs:25:2038:25:2043 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | [post] this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1340:25:1348 | ... > ... | +| UseUseExplosion.cs:25:1340:25:1343 | access to property Prop | UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:1357:25:1360 | this access | +| UseUseExplosion.cs:25:1340:25:1343 | this access | UseUseExplosion.cs:25:2023:25:2028 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | [post] this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1357:25:1365 | ... > ... | +| UseUseExplosion.cs:25:1357:25:1360 | access to property Prop | UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:1374:25:1377 | this access | +| UseUseExplosion.cs:25:1357:25:1360 | this access | UseUseExplosion.cs:25:2008:25:2013 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | [post] this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1374:25:1382 | ... > ... | +| UseUseExplosion.cs:25:1374:25:1377 | access to property Prop | UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1391:25:1394 | this access | +| UseUseExplosion.cs:25:1374:25:1377 | this access | UseUseExplosion.cs:25:1993:25:1998 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | [post] this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1391:25:1399 | ... > ... | +| UseUseExplosion.cs:25:1391:25:1394 | access to property Prop | UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1408:25:1411 | this access | +| UseUseExplosion.cs:25:1391:25:1394 | this access | UseUseExplosion.cs:25:1978:25:1983 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | [post] this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1408:25:1416 | ... > ... | +| UseUseExplosion.cs:25:1408:25:1411 | access to property Prop | UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1425:25:1428 | this access | +| UseUseExplosion.cs:25:1408:25:1411 | this access | UseUseExplosion.cs:25:1963:25:1968 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | [post] this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1425:25:1433 | ... > ... | +| UseUseExplosion.cs:25:1425:25:1428 | access to property Prop | UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1442:25:1445 | this access | +| UseUseExplosion.cs:25:1425:25:1428 | this access | UseUseExplosion.cs:25:1948:25:1953 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | [post] this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1442:25:1450 | ... > ... | +| UseUseExplosion.cs:25:1442:25:1445 | access to property Prop | UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1459:25:1462 | this access | +| UseUseExplosion.cs:25:1442:25:1445 | this access | UseUseExplosion.cs:25:1933:25:1938 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | [post] this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1459:25:1467 | ... > ... | +| UseUseExplosion.cs:25:1459:25:1462 | access to property Prop | UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1476:25:1479 | this access | +| UseUseExplosion.cs:25:1459:25:1462 | this access | UseUseExplosion.cs:25:1918:25:1923 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | [post] this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1476:25:1484 | ... > ... | +| UseUseExplosion.cs:25:1476:25:1479 | access to property Prop | UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1493:25:1496 | this access | +| UseUseExplosion.cs:25:1476:25:1479 | this access | UseUseExplosion.cs:25:1903:25:1908 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | [post] this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1493:25:1501 | ... > ... | +| UseUseExplosion.cs:25:1493:25:1496 | access to property Prop | UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1510:25:1513 | this access | +| UseUseExplosion.cs:25:1493:25:1496 | this access | UseUseExplosion.cs:25:1888:25:1893 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | [post] this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1510:25:1518 | ... > ... | +| UseUseExplosion.cs:25:1510:25:1513 | access to property Prop | UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1527:25:1530 | this access | +| UseUseExplosion.cs:25:1510:25:1513 | this access | UseUseExplosion.cs:25:1873:25:1878 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | [post] this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1527:25:1535 | ... > ... | +| UseUseExplosion.cs:25:1527:25:1530 | access to property Prop | UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1544:25:1547 | this access | +| UseUseExplosion.cs:25:1527:25:1530 | this access | UseUseExplosion.cs:25:1858:25:1863 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | [post] this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1544:25:1552 | ... > ... | +| UseUseExplosion.cs:25:1544:25:1547 | access to property Prop | UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1561:25:1564 | this access | +| UseUseExplosion.cs:25:1544:25:1547 | this access | UseUseExplosion.cs:25:1843:25:1848 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | [post] this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1561:25:1568 | ... > ... | +| UseUseExplosion.cs:25:1561:25:1564 | access to property Prop | UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1577:25:1580 | this access | +| UseUseExplosion.cs:25:1561:25:1564 | this access | UseUseExplosion.cs:25:1828:25:1833 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | [post] this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1577:25:1584 | ... > ... | +| UseUseExplosion.cs:25:1577:25:1580 | access to property Prop | UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1593:25:1596 | this access | +| UseUseExplosion.cs:25:1577:25:1580 | this access | UseUseExplosion.cs:25:1813:25:1818 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | [post] this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1593:25:1600 | ... > ... | +| UseUseExplosion.cs:25:1593:25:1596 | access to property Prop | UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1609:25:1612 | this access | +| UseUseExplosion.cs:25:1593:25:1596 | this access | UseUseExplosion.cs:25:1798:25:1803 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | [post] this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1609:25:1616 | ... > ... | +| UseUseExplosion.cs:25:1609:25:1612 | access to property Prop | UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1625:25:1628 | this access | +| UseUseExplosion.cs:25:1609:25:1612 | this access | UseUseExplosion.cs:25:1783:25:1788 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | [post] this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1625:25:1632 | ... > ... | +| UseUseExplosion.cs:25:1625:25:1628 | access to property Prop | UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1641:25:1644 | this access | +| UseUseExplosion.cs:25:1625:25:1628 | this access | UseUseExplosion.cs:25:1768:25:1773 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | [post] this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1641:25:1648 | ... > ... | +| UseUseExplosion.cs:25:1641:25:1644 | access to property Prop | UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1657:25:1660 | this access | +| UseUseExplosion.cs:25:1641:25:1644 | this access | UseUseExplosion.cs:25:1753:25:1758 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | [post] this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1657:25:1664 | ... > ... | +| UseUseExplosion.cs:25:1657:25:1660 | access to property Prop | UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1673:25:1676 | this access | +| UseUseExplosion.cs:25:1657:25:1660 | this access | UseUseExplosion.cs:25:1738:25:1743 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | [post] this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1673:25:1680 | ... > ... | +| UseUseExplosion.cs:25:1673:25:1676 | access to property Prop | UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1689:25:1692 | this access | +| UseUseExplosion.cs:25:1673:25:1676 | this access | UseUseExplosion.cs:25:1723:25:1728 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | [post] this access | UseUseExplosion.cs:25:1708:25:1713 | this access | +| UseUseExplosion.cs:25:1689:25:1692 | access to property Prop | UseUseExplosion.cs:25:1689:25:1696 | ... > ... | +| UseUseExplosion.cs:25:1689:25:1692 | this access | UseUseExplosion.cs:25:1708:25:1713 | this access | diff --git a/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs b/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs new file mode 100644 index 00000000000..b062aeba8f5 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs @@ -0,0 +1,29 @@ +class C +{ + int Prop { get; set; } + + // Should generate 100 + 100 local use-use flow steps for `x`, and not 100 * 100 + // + // Generated by quick-evaling `gen/0` below: + // + // ```ql + // string gen(int depth) { + // depth in [0 .. 100] and + // ( + // if depth = 0 + // then result = "" + // else result = "if (Prop > " + depth + ") { " + gen(depth - 1) + " } else Use(x);" + // ) + // } + // + // string gen() { result = "var x = 0;\n" + gen(100) + "\n" + gen(100) } + // ``` + void M() + { + var x = 0; + if (Prop > 100) { if (Prop > 99) { if (Prop > 98) { if (Prop > 97) { if (Prop > 96) { if (Prop > 95) { if (Prop > 94) { if (Prop > 93) { if (Prop > 92) { if (Prop > 91) { if (Prop > 90) { if (Prop > 89) { if (Prop > 88) { if (Prop > 87) { if (Prop > 86) { if (Prop > 85) { if (Prop > 84) { if (Prop > 83) { if (Prop > 82) { if (Prop > 81) { if (Prop > 80) { if (Prop > 79) { if (Prop > 78) { if (Prop > 77) { if (Prop > 76) { if (Prop > 75) { if (Prop > 74) { if (Prop > 73) { if (Prop > 72) { if (Prop > 71) { if (Prop > 70) { if (Prop > 69) { if (Prop > 68) { if (Prop > 67) { if (Prop > 66) { if (Prop > 65) { if (Prop > 64) { if (Prop > 63) { if (Prop > 62) { if (Prop > 61) { if (Prop > 60) { if (Prop > 59) { if (Prop > 58) { if (Prop > 57) { if (Prop > 56) { if (Prop > 55) { if (Prop > 54) { if (Prop > 53) { if (Prop > 52) { if (Prop > 51) { if (Prop > 50) { if (Prop > 49) { if (Prop > 48) { if (Prop > 47) { if (Prop > 46) { if (Prop > 45) { if (Prop > 44) { if (Prop > 43) { if (Prop > 42) { if (Prop > 41) { if (Prop > 40) { if (Prop > 39) { if (Prop > 38) { if (Prop > 37) { if (Prop > 36) { if (Prop > 35) { if (Prop > 34) { if (Prop > 33) { if (Prop > 32) { if (Prop > 31) { if (Prop > 30) { if (Prop > 29) { if (Prop > 28) { if (Prop > 27) { if (Prop > 26) { if (Prop > 25) { if (Prop > 24) { if (Prop > 23) { if (Prop > 22) { if (Prop > 21) { if (Prop > 20) { if (Prop > 19) { if (Prop > 18) { if (Prop > 17) { if (Prop > 16) { if (Prop > 15) { if (Prop > 14) { if (Prop > 13) { if (Prop > 12) { if (Prop > 11) { if (Prop > 10) { if (Prop > 9) { if (Prop > 8) { if (Prop > 7) { if (Prop > 6) { if (Prop > 5) { if (Prop > 4) { if (Prop > 3) { if (Prop > 2) { if (Prop > 1) { } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); + if (Prop > 100) { if (Prop > 99) { if (Prop > 98) { if (Prop > 97) { if (Prop > 96) { if (Prop > 95) { if (Prop > 94) { if (Prop > 93) { if (Prop > 92) { if (Prop > 91) { if (Prop > 90) { if (Prop > 89) { if (Prop > 88) { if (Prop > 87) { if (Prop > 86) { if (Prop > 85) { if (Prop > 84) { if (Prop > 83) { if (Prop > 82) { if (Prop > 81) { if (Prop > 80) { if (Prop > 79) { if (Prop > 78) { if (Prop > 77) { if (Prop > 76) { if (Prop > 75) { if (Prop > 74) { if (Prop > 73) { if (Prop > 72) { if (Prop > 71) { if (Prop > 70) { if (Prop > 69) { if (Prop > 68) { if (Prop > 67) { if (Prop > 66) { if (Prop > 65) { if (Prop > 64) { if (Prop > 63) { if (Prop > 62) { if (Prop > 61) { if (Prop > 60) { if (Prop > 59) { if (Prop > 58) { if (Prop > 57) { if (Prop > 56) { if (Prop > 55) { if (Prop > 54) { if (Prop > 53) { if (Prop > 52) { if (Prop > 51) { if (Prop > 50) { if (Prop > 49) { if (Prop > 48) { if (Prop > 47) { if (Prop > 46) { if (Prop > 45) { if (Prop > 44) { if (Prop > 43) { if (Prop > 42) { if (Prop > 41) { if (Prop > 40) { if (Prop > 39) { if (Prop > 38) { if (Prop > 37) { if (Prop > 36) { if (Prop > 35) { if (Prop > 34) { if (Prop > 33) { if (Prop > 32) { if (Prop > 31) { if (Prop > 30) { if (Prop > 29) { if (Prop > 28) { if (Prop > 27) { if (Prop > 26) { if (Prop > 25) { if (Prop > 24) { if (Prop > 23) { if (Prop > 22) { if (Prop > 21) { if (Prop > 20) { if (Prop > 19) { if (Prop > 18) { if (Prop > 17) { if (Prop > 16) { if (Prop > 15) { if (Prop > 14) { if (Prop > 13) { if (Prop > 12) { if (Prop > 11) { if (Prop > 10) { if (Prop > 9) { if (Prop > 8) { if (Prop > 7) { if (Prop > 6) { if (Prop > 5) { if (Prop > 4) { if (Prop > 3) { if (Prop > 2) { if (Prop > 1) { } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); } else Use(x); + } + + void Use(int i) { } +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs b/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs index f6cce7f149a..798f106e9f6 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs +++ b/csharp/ql/test/library-tests/dataflow/ssa-large/Large.cs @@ -2886,7 +2886,7 @@ public class Large // ( // if depth = 0 // then result = "" - // else else result = "if (Prop > " + depth + ") { " + gen(depth - 1, var) + " } else Use(" + var + ");" + // else result = "if (Prop > " + depth + ") { " + gen(depth - 1, var) + " } else Use(" + var + ");" // ) // } // diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected index 19c394b58fd..970e6fce524 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.expected @@ -1,4 +1,30 @@ -| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:30:80:31 | access to local variable x1 | -| Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:63:16:63:28 | this access | -| Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:63:16:63:16 | access to parameter i | -| Test.cs:78:13:78:13 | x | Test.cs:90:9:97:9 | if (...) ... | +phiReadNode +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | +phiReadNodeRead +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:37:80:42 | access to field Field2 | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:65:24:65:32 | access to field LoopField | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o | Patterns.cs:20:17:20:17 | access to local variable o | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:65:24:65:31 | access to property LoopProp | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:92:17:92:17 | access to local variable x | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:96:17:96:17 | access to local variable x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:99:13:99:13 | access to local variable x | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:104:17:104:17 | access to local variable x | +phiReadInput +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:18 | SSA def(this.Field2) | +| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | +| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | +| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:23 | SSA def(o) | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | +| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:24:9:24:15 | SSA phi(x) | +| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:25:16:25:16 | SSA phi read(x) | +| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:17 | SSA def(x) | +| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:90:9:97:9 | SSA phi read(x) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql index f9603dc1da2..8fee62217bf 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql +++ b/csharp/ql/test/library-tests/dataflow/ssa/SSAPhiRead.ql @@ -1,6 +1,17 @@ import csharp import semmle.code.csharp.dataflow.internal.SsaImpl +import ExposedForTestingOnly -from Ssa::SourceVariable v, ControlFlow::BasicBlock bb -where phiReadExposedForTesting(bb, v) -select v, bb +query predicate phiReadNode(PhiReadNode phi, Ssa::SourceVariable v) { phi.getSourceVariable() = v } + +query predicate phiReadNodeRead(PhiReadNode phi, Ssa::SourceVariable v, ControlFlow::Node read) { + phi.getSourceVariable() = v and + exists(ControlFlow::BasicBlock bb, int i | + ssaDefReachesReadExt(v, phi, bb, i) and + read = bb.getNode(i) + ) +} + +query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) { + phiHasInputFromBlockExt(phi, inp, _) +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa/Test.cs b/csharp/ql/test/library-tests/dataflow/ssa/Test.cs index 5d321d0117d..23fee7d4706 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/Test.cs +++ b/csharp/ql/test/library-tests/dataflow/ssa/Test.cs @@ -95,7 +95,7 @@ class Test { use(x); } - // no phi_use for `x`, because actual use exists in the block + // phi_use for `x`, even though there is an actual use in the block use(x); diff --git a/csharp/ql/test/library-tests/delegates/Delegates2.ql b/csharp/ql/test/library-tests/delegates/Delegates2.ql index 951c7ab9724..1ce83492659 100644 --- a/csharp/ql/test/library-tests/delegates/Delegates2.ql +++ b/csharp/ql/test/library-tests/delegates/Delegates2.ql @@ -6,7 +6,7 @@ import csharp from DelegateType d where - d.hasQualifiedName("Delegates.FooDelegate") and + d.hasQualifiedName("Delegates", "FooDelegate") and d.getReturnType() instanceof DoubleType and d.getParameter(0).hasName("param") and d.getParameter(0).isRef() and diff --git a/csharp/ql/test/library-tests/delegates/Delegates3.ql b/csharp/ql/test/library-tests/delegates/Delegates3.ql index 88c019b3067..08fc413249c 100644 --- a/csharp/ql/test/library-tests/delegates/Delegates3.ql +++ b/csharp/ql/test/library-tests/delegates/Delegates3.ql @@ -6,7 +6,7 @@ import csharp from DelegateType d where - d.hasQualifiedName("System.Threading.ContextCallback") and + d.hasQualifiedName("System.Threading", "ContextCallback") and d.getNumberOfParameters() = 1 and d.getParameter(0).hasName("state") and d.getParameter(0).isValue() and diff --git a/csharp/ql/test/library-tests/enums/Enums1.ql b/csharp/ql/test/library-tests/enums/Enums1.ql index f9978014487..ede536a2695 100644 --- a/csharp/ql/test/library-tests/enums/Enums1.ql +++ b/csharp/ql/test/library-tests/enums/Enums1.ql @@ -7,5 +7,5 @@ import csharp from EnumConstant c where c.getName() = "Red" and - c.getDeclaringType().hasQualifiedName("Enums.Color") + c.getDeclaringType().hasQualifiedName("Enums", "Color") select c, c.getType() diff --git a/csharp/ql/test/library-tests/enums/Enums10.ql b/csharp/ql/test/library-tests/enums/Enums10.ql index 21bb8019785..ced6b3709f9 100644 --- a/csharp/ql/test/library-tests/enums/Enums10.ql +++ b/csharp/ql/test/library-tests/enums/Enums10.ql @@ -8,7 +8,7 @@ from EnumConstant c, EnumConstant d where c.getName() = "Blue" and d.hasName("AnotherBlue") and - c.getDeclaringType().hasQualifiedName("Enums.SparseColor") and + c.getDeclaringType().hasQualifiedName("Enums", "SparseColor") and c.getType() = c.getDeclaringType() and c.getType() = d.getType() and c.getValue() = "11" and diff --git a/csharp/ql/test/library-tests/enums/Enums2.ql b/csharp/ql/test/library-tests/enums/Enums2.ql index eda8843c3c8..97c68efd774 100644 --- a/csharp/ql/test/library-tests/enums/Enums2.ql +++ b/csharp/ql/test/library-tests/enums/Enums2.ql @@ -7,7 +7,7 @@ import csharp from EnumConstant c where c.getName() = "Green" and - c.getDeclaringType().hasQualifiedName("Enums.Color") and + c.getDeclaringType().hasQualifiedName("Enums", "Color") and c.getType() = c.getDeclaringType() and c.getUnderlyingType() instanceof IntType select c diff --git a/csharp/ql/test/library-tests/enums/Enums3.ql b/csharp/ql/test/library-tests/enums/Enums3.ql index 4cbb3e65e4d..57d46ac987a 100644 --- a/csharp/ql/test/library-tests/enums/Enums3.ql +++ b/csharp/ql/test/library-tests/enums/Enums3.ql @@ -3,11 +3,13 @@ */ import csharp +import semmle.code.csharp.commons.QualifiedName -from EnumConstant c +from EnumConstant c, string namespace, string name where c.getName() = "Green" and - c.getDeclaringType().hasQualifiedName("Enums.LongColor") and + c.getDeclaringType().hasQualifiedName("Enums", "LongColor") and c.getType() = c.getDeclaringType() and - c.getValue() = "1" -select c, c.getDeclaringType().getBaseClass().getQualifiedName() + c.getValue() = "1" and + c.getDeclaringType().getBaseClass().hasQualifiedName(namespace, name) +select c, getQualifiedName(namespace, name) diff --git a/csharp/ql/test/library-tests/enums/Enums4.ql b/csharp/ql/test/library-tests/enums/Enums4.ql index 087c6b1f576..5a16ffb7c4c 100644 --- a/csharp/ql/test/library-tests/enums/Enums4.ql +++ b/csharp/ql/test/library-tests/enums/Enums4.ql @@ -4,5 +4,5 @@ import csharp -where forall(Enum e | e.getBaseClass().hasQualifiedName("System.Enum")) +where forall(Enum e | e.getBaseClass().hasQualifiedName("System", "Enum")) select 1 diff --git a/csharp/ql/test/library-tests/enums/Enums6.ql b/csharp/ql/test/library-tests/enums/Enums6.ql index 93e03a3e787..3e9332e2890 100644 --- a/csharp/ql/test/library-tests/enums/Enums6.ql +++ b/csharp/ql/test/library-tests/enums/Enums6.ql @@ -7,7 +7,7 @@ import csharp from EnumConstant c where c.getName() = "FourBlue" and - c.getDeclaringType().hasQualifiedName("Enums.ValueColor") and + c.getDeclaringType().hasQualifiedName("Enums", "ValueColor") and c.getType() = c.getDeclaringType() and c.getValue() = "4" and c.getUnderlyingType() instanceof UIntType diff --git a/csharp/ql/test/library-tests/enums/Enums7.ql b/csharp/ql/test/library-tests/enums/Enums7.ql index 93e03a3e787..3e9332e2890 100644 --- a/csharp/ql/test/library-tests/enums/Enums7.ql +++ b/csharp/ql/test/library-tests/enums/Enums7.ql @@ -7,7 +7,7 @@ import csharp from EnumConstant c where c.getName() = "FourBlue" and - c.getDeclaringType().hasQualifiedName("Enums.ValueColor") and + c.getDeclaringType().hasQualifiedName("Enums", "ValueColor") and c.getType() = c.getDeclaringType() and c.getValue() = "4" and c.getUnderlyingType() instanceof UIntType diff --git a/csharp/ql/test/library-tests/enums/Enums8.ql b/csharp/ql/test/library-tests/enums/Enums8.ql index 26ac31db457..03086265795 100644 --- a/csharp/ql/test/library-tests/enums/Enums8.ql +++ b/csharp/ql/test/library-tests/enums/Enums8.ql @@ -7,7 +7,7 @@ import csharp from EnumConstant c where c.getName() = "Red" and - c.getDeclaringType().hasQualifiedName("Enums.SparseColor") and + c.getDeclaringType().hasQualifiedName("Enums", "SparseColor") and c.getType() = c.getDeclaringType() and c.getValue() = "0" and c.getUnderlyingType() instanceof IntType and diff --git a/csharp/ql/test/library-tests/enums/Enums9.ql b/csharp/ql/test/library-tests/enums/Enums9.ql index 895764920f7..b1ad791b758 100644 --- a/csharp/ql/test/library-tests/enums/Enums9.ql +++ b/csharp/ql/test/library-tests/enums/Enums9.ql @@ -7,7 +7,7 @@ import csharp from EnumConstant c where c.getName() = "Green" and - c.getDeclaringType().hasQualifiedName("Enums.SparseColor") and + c.getDeclaringType().hasQualifiedName("Enums", "SparseColor") and c.getType() = c.getDeclaringType() and c.getValue() = "10" and c.getUnderlyingType() instanceof IntType and diff --git a/csharp/ql/test/library-tests/events/Events1.ql b/csharp/ql/test/library-tests/events/Events1.ql index 5be331349b1..39cd0365a19 100644 --- a/csharp/ql/test/library-tests/events/Events1.ql +++ b/csharp/ql/test/library-tests/events/Events1.ql @@ -7,6 +7,6 @@ import csharp from Event e where e.getName() = "Click" and - e.getDeclaringType().hasQualifiedName("Events.Button") and + e.getDeclaringType().hasQualifiedName("Events", "Button") and e.isPublic() select e, e.getType() diff --git a/csharp/ql/test/library-tests/events/Events2.ql b/csharp/ql/test/library-tests/events/Events2.ql index 3ff06e1a4d4..ef5a08d1f8f 100644 --- a/csharp/ql/test/library-tests/events/Events2.ql +++ b/csharp/ql/test/library-tests/events/Events2.ql @@ -7,6 +7,6 @@ import csharp from Event e where e.getName() = "Click" and - e.getDeclaringType().hasQualifiedName("Events.Button") and + e.getDeclaringType().hasQualifiedName("Events", "Button") and e.isFieldLike() select e, e.getType() diff --git a/csharp/ql/test/library-tests/events/Events3.ql b/csharp/ql/test/library-tests/events/Events3.ql index b90a358b43a..97a03e97ecb 100644 --- a/csharp/ql/test/library-tests/events/Events3.ql +++ b/csharp/ql/test/library-tests/events/Events3.ql @@ -7,6 +7,6 @@ import csharp from Event e where e.getName() = "Click" and - e.getDeclaringType().hasQualifiedName("Events.Button") and + e.getDeclaringType().hasQualifiedName("Events", "Button") and e.getType().hasName("EventHandler") select e, e.getType() diff --git a/csharp/ql/test/library-tests/events/Events4.ql b/csharp/ql/test/library-tests/events/Events4.ql index 7250c0b2c1c..3213e28b03b 100644 --- a/csharp/ql/test/library-tests/events/Events4.ql +++ b/csharp/ql/test/library-tests/events/Events4.ql @@ -7,7 +7,7 @@ import csharp from Event e where e.getName() = "MouseUp" and - e.getDeclaringType().hasQualifiedName("Events.Control") and + e.getDeclaringType().hasQualifiedName("Events", "Control") and e.getType().hasName("EventHandler") and e.isPublic() select e, e.getType() diff --git a/csharp/ql/test/library-tests/events/Events5.ql b/csharp/ql/test/library-tests/events/Events5.ql index 259ac14966d..3aed44b4f6d 100644 --- a/csharp/ql/test/library-tests/events/Events5.ql +++ b/csharp/ql/test/library-tests/events/Events5.ql @@ -6,7 +6,7 @@ import csharp where count(Event e | - e.getDeclaringType().hasQualifiedName("Events.Control") and + e.getDeclaringType().hasQualifiedName("Events", "Control") and e.getType().hasName("EventHandler") and e.isPublic() ) = 2 diff --git a/csharp/ql/test/library-tests/events/Events7.ql b/csharp/ql/test/library-tests/events/Events7.ql index 407d69be06d..0d6c31630b8 100644 --- a/csharp/ql/test/library-tests/events/Events7.ql +++ b/csharp/ql/test/library-tests/events/Events7.ql @@ -7,6 +7,6 @@ import csharp from Event e where e.getName() = "MouseUp" and - e.getDeclaringType().hasQualifiedName("Events.Control") and + e.getDeclaringType().hasQualifiedName("Events", "Control") and not e.isFieldLike() select e, e.getType() diff --git a/csharp/ql/test/library-tests/expressions/As1.ql b/csharp/ql/test/library-tests/expressions/As1.ql index 6c436883d13..451a6c3c099 100644 --- a/csharp/ql/test/library-tests/expressions/As1.ql +++ b/csharp/ql/test/library-tests/expressions/As1.ql @@ -9,6 +9,6 @@ where m.hasName("MainIsAsCast") and e.getEnclosingCallable() = m and e.getExpr().(ParameterAccess).getTarget().getName() = "o" and - e.getTargetType().(Class).hasQualifiedName("Expressions.Class") and + e.getTargetType().(Class).hasQualifiedName("Expressions", "Class") and e.getEnclosingStmt().getParent().getParent() instanceof IfStmt select m, e diff --git a/csharp/ql/test/library-tests/expressions/Cast1.ql b/csharp/ql/test/library-tests/expressions/Cast1.ql index d7f812326ef..5233c6066c3 100644 --- a/csharp/ql/test/library-tests/expressions/Cast1.ql +++ b/csharp/ql/test/library-tests/expressions/Cast1.ql @@ -9,6 +9,6 @@ where m.hasName("MainIsAsCast") and e.getEnclosingCallable() = m and e.getExpr().(ParameterAccess).getTarget().getName() = "p" and - e.getTargetType().(Class).hasQualifiedName("Expressions.Class") and + e.getTargetType().(Class).hasQualifiedName("Expressions", "Class") and e.getEnclosingStmt().getParent().getParent() instanceof IfStmt select m, e diff --git a/csharp/ql/test/library-tests/expressions/DelegateCall3.ql b/csharp/ql/test/library-tests/expressions/DelegateCall3.ql index b68b35dde45..af7cf0bba16 100644 --- a/csharp/ql/test/library-tests/expressions/DelegateCall3.ql +++ b/csharp/ql/test/library-tests/expressions/DelegateCall3.ql @@ -10,5 +10,5 @@ where e.getEnclosingCallable() = m and e.getExpr() = a and a.getTarget().hasName("cd7") and - a.getTarget().getType().(DelegateType).hasQualifiedName("Expressions.D") + a.getTarget().getType().(DelegateType).hasQualifiedName("Expressions", "D") select m, e, a diff --git a/csharp/ql/test/library-tests/expressions/Is1.ql b/csharp/ql/test/library-tests/expressions/Is1.ql index 705b7a98ad4..baa85f62da2 100644 --- a/csharp/ql/test/library-tests/expressions/Is1.ql +++ b/csharp/ql/test/library-tests/expressions/Is1.ql @@ -10,5 +10,5 @@ where e.getEnclosingCallable() = m and e.getExpr().(ParameterAccess).getTarget().getName() = "o" and tpe = e.getPattern() and - tpe.getCheckedType().(Class).hasQualifiedName("Expressions.Class") + tpe.getCheckedType().(Class).hasQualifiedName("Expressions", "Class") select m, e diff --git a/csharp/ql/test/library-tests/fields/Constants1.ql b/csharp/ql/test/library-tests/fields/Constants1.ql index 587a38b5731..9759e49893e 100644 --- a/csharp/ql/test/library-tests/fields/Constants1.ql +++ b/csharp/ql/test/library-tests/fields/Constants1.ql @@ -7,7 +7,7 @@ import csharp from MemberConstant c where c.getName() = "X" and - c.getDeclaringType().hasQualifiedName("Constants.A") and + c.getDeclaringType().hasQualifiedName("Constants", "A") and c.getType() instanceof IntType and c.getInitializer() instanceof BinaryOperation and c.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Constants2.ql b/csharp/ql/test/library-tests/fields/Constants2.ql index 908c1f7c5c9..ec28d999150 100644 --- a/csharp/ql/test/library-tests/fields/Constants2.ql +++ b/csharp/ql/test/library-tests/fields/Constants2.ql @@ -7,7 +7,7 @@ import csharp from MemberConstant c where c.getName() = "Y" and - c.getDeclaringType().hasQualifiedName("Constants.A") and + c.getDeclaringType().hasQualifiedName("Constants", "A") and c.getType() instanceof IntType and c.getInitializer() instanceof IntLiteral and c.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Constants3.ql b/csharp/ql/test/library-tests/fields/Constants3.ql index e2bb2d9e34a..38af03d0676 100644 --- a/csharp/ql/test/library-tests/fields/Constants3.ql +++ b/csharp/ql/test/library-tests/fields/Constants3.ql @@ -7,7 +7,7 @@ import csharp from MemberConstant c where c.getName() = "Z" and - c.getDeclaringType().hasQualifiedName("Constants.B") and + c.getDeclaringType().hasQualifiedName("Constants", "B") and c.getType() instanceof IntType and c.getInitializer() instanceof BinaryOperation and c.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields1.ql b/csharp/ql/test/library-tests/fields/Fields1.ql index 7e7c5dfbc95..dd85903934c 100644 --- a/csharp/ql/test/library-tests/fields/Fields1.ql +++ b/csharp/ql/test/library-tests/fields/Fields1.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "X" and - f.getDeclaringType().hasQualifiedName("Fields.A") and + f.getDeclaringType().hasQualifiedName("Fields", "A") and f.getType() instanceof IntType and f.getInitializer().(IntLiteral).getValue() = "1" and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields10.ql b/csharp/ql/test/library-tests/fields/Fields10.ql index fa17e74d69b..5b5bbf7d808 100644 --- a/csharp/ql/test/library-tests/fields/Fields10.ql +++ b/csharp/ql/test/library-tests/fields/Fields10.ql @@ -8,6 +8,6 @@ from Field f, SimpleType t where f.getName() = "MaxValue" and f.getDeclaringType() = t and - t.hasQualifiedName("System.Decimal") and + t.hasQualifiedName("System", "Decimal") and f.isPublic() select f.toString(), f.getDeclaringType().toString() diff --git a/csharp/ql/test/library-tests/fields/Fields2.ql b/csharp/ql/test/library-tests/fields/Fields2.ql index 9a970e1eed9..ef4e737a635 100644 --- a/csharp/ql/test/library-tests/fields/Fields2.ql +++ b/csharp/ql/test/library-tests/fields/Fields2.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "Y" and - f.getDeclaringType().hasQualifiedName("Fields.A") and + f.getDeclaringType().hasQualifiedName("Fields", "A") and f.getType() instanceof IntType and not exists(f.getInitializer()) and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields3.ql b/csharp/ql/test/library-tests/fields/Fields3.ql index a6a4fade742..2bfdc558d08 100644 --- a/csharp/ql/test/library-tests/fields/Fields3.ql +++ b/csharp/ql/test/library-tests/fields/Fields3.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "Z" and - f.getDeclaringType().hasQualifiedName("Fields.A") and + f.getDeclaringType().hasQualifiedName("Fields", "A") and f.getType() instanceof IntType and f.getInitializer().(IntLiteral).getValue() = "100" and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields4.ql b/csharp/ql/test/library-tests/fields/Fields4.ql index f6c01e4e322..96c88c178cf 100644 --- a/csharp/ql/test/library-tests/fields/Fields4.ql +++ b/csharp/ql/test/library-tests/fields/Fields4.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "X" and - f.getDeclaringType().hasQualifiedName("Fields.B") and + f.getDeclaringType().hasQualifiedName("Fields", "B") and f.getType() instanceof IntType and f.getInitializer().(IntLiteral).getValue() = "1" and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields5.ql b/csharp/ql/test/library-tests/fields/Fields5.ql index eeaf4996e0c..2ff6d63581c 100644 --- a/csharp/ql/test/library-tests/fields/Fields5.ql +++ b/csharp/ql/test/library-tests/fields/Fields5.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "Y" and - f.getDeclaringType().hasQualifiedName("Fields.B") and + f.getDeclaringType().hasQualifiedName("Fields", "B") and f.getType() instanceof IntType and not exists(f.getInitializer()) and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields6.ql b/csharp/ql/test/library-tests/fields/Fields6.ql index 8706c829205..8967586b86b 100644 --- a/csharp/ql/test/library-tests/fields/Fields6.ql +++ b/csharp/ql/test/library-tests/fields/Fields6.ql @@ -7,7 +7,7 @@ import csharp from Field f where f.getName() = "finished" and - f.getDeclaringType().hasQualifiedName("Fields.Application") and + f.getDeclaringType().hasQualifiedName("Fields", "Application") and f.getType() instanceof BoolType and not exists(f.getInitializer()) and f.isPublic() and diff --git a/csharp/ql/test/library-tests/fields/Fields7.ql b/csharp/ql/test/library-tests/fields/Fields7.ql index 5097de7923f..3c031831ab6 100644 --- a/csharp/ql/test/library-tests/fields/Fields7.ql +++ b/csharp/ql/test/library-tests/fields/Fields7.ql @@ -8,7 +8,7 @@ from Field f, UnboundGenericClass c where f.getName() = "count" and f.getDeclaringType() = c and - c.hasQualifiedName("Fields.C<>") and + c.hasQualifiedName("Fields", "C<>") and f.getType() instanceof IntType and f.isStatic() select f, f.getDeclaringType() diff --git a/csharp/ql/test/library-tests/fields/Fields8.ql b/csharp/ql/test/library-tests/fields/Fields8.ql index 5097de7923f..3c031831ab6 100644 --- a/csharp/ql/test/library-tests/fields/Fields8.ql +++ b/csharp/ql/test/library-tests/fields/Fields8.ql @@ -8,7 +8,7 @@ from Field f, UnboundGenericClass c where f.getName() = "count" and f.getDeclaringType() = c and - c.hasQualifiedName("Fields.C<>") and + c.hasQualifiedName("Fields", "C<>") and f.getType() instanceof IntType and f.isStatic() select f, f.getDeclaringType() diff --git a/csharp/ql/test/library-tests/fields/Fields9.ql b/csharp/ql/test/library-tests/fields/Fields9.ql index 24a601da86a..9bb87878ee3 100644 --- a/csharp/ql/test/library-tests/fields/Fields9.ql +++ b/csharp/ql/test/library-tests/fields/Fields9.ql @@ -8,7 +8,7 @@ from Field f, Class c where f.getName() = "Black" and f.getDeclaringType() = c and - c.hasQualifiedName("Fields.Color") and + c.hasQualifiedName("Fields", "Color") and f.getType() = c and f.isStatic() and f.isPublic() and diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index ae10cc17e9d..2d5a35839fb 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -131,7 +131,7 @@ summary | System.Data.Entity;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | | System.Data.Entity;DbSet<>;false;Update;(T);;Argument[0];Argument[this].Element;value;manual | | System.Data.Entity;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -negativeSummary +neutral sourceNode sinkNode | EntityFrameworkCore.cs:72:36:72:40 | "sql" | sql | diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql index 41cc8379b3d..00873833083 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql @@ -2,8 +2,7 @@ import semmle.code.csharp.frameworks.EntityFramework::EntityFramework import shared.FlowSummaries import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow -private class IncludeEFSummarizedCallable extends IncludeSummarizedCallable { - IncludeEFSummarizedCallable() { this instanceof EFSummarizedCallable } +private class IncludeEFSummarizedCallable extends IncludeSummarizedCallable instanceof EFSummarizedCallable { } query predicate sourceNode(DataFlow::Node node, string kind) { diff --git a/csharp/ql/test/library-tests/generics/Generics.ql b/csharp/ql/test/library-tests/generics/Generics.ql index 4b43baa6fca..b0c1623b68a 100644 --- a/csharp/ql/test/library-tests/generics/Generics.ql +++ b/csharp/ql/test/library-tests/generics/Generics.ql @@ -1,4 +1,5 @@ import csharp +import semmle.code.csharp.commons.QualifiedName query predicate test1(UnboundGenericDelegateType d) { d.hasName("GenericDelegate<>") and @@ -259,18 +260,24 @@ query predicate test32(ConstructedGeneric cg, string s1, string s2) { query predicate test33(ConstructedMethod cm, string s1, string s2) { cm.fromSource() and - cm.getQualifiedName() = s1 and + exists(string namespace, string type, string name | + cm.hasQualifiedName(namespace, type, name) and s1 = getQualifiedName(namespace, type, name) + ) and cm.getQualifiedNameWithTypes() = s2 } query predicate test34(UnboundGeneric ug, string s1, string s2) { ug.fromSource() and - ug.getQualifiedName() = s1 and + exists(string qualifier, string name | + ug.hasQualifiedName(qualifier, name) and s1 = getQualifiedName(qualifier, name) + ) and ug.getQualifiedNameWithTypes() = s2 } query predicate test35(UnboundGenericMethod gm, string s1, string s2) { gm.fromSource() and - gm.getQualifiedName() = s1 and + exists(string namespace, string type, string name | + gm.hasQualifiedName(namespace, type, name) and s1 = getQualifiedName(namespace, type, name) + ) and gm.getQualifiedNameWithTypes() = s2 } diff --git a/csharp/ql/test/library-tests/indexers/Indexers10.ql b/csharp/ql/test/library-tests/indexers/Indexers10.ql index a8329523315..2d1c7aee3a7 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers10.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers10.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.Grid") and + i.getDeclaringType().hasQualifiedName("Indexers", "Grid") and i.getType() instanceof IntType and i.isPublic() and i.isReadWrite() diff --git a/csharp/ql/test/library-tests/indexers/Indexers2.ql b/csharp/ql/test/library-tests/indexers/Indexers2.ql index 6065ae9abb8..ef470e73bad 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers2.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers2.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.BitArray") and + i.getDeclaringType().hasQualifiedName("Indexers", "BitArray") and i.getType() instanceof BoolType and i.getDimension() = 1 select i diff --git a/csharp/ql/test/library-tests/indexers/Indexers3.ql b/csharp/ql/test/library-tests/indexers/Indexers3.ql index 9b38e6f6751..f6f116ab70d 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers3.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers3.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.BitArray") and + i.getDeclaringType().hasQualifiedName("Indexers", "BitArray") and i.getType() instanceof BoolType and i.getParameter(0).getName() = "index" and i.getParameter(0).getType() instanceof IntType diff --git a/csharp/ql/test/library-tests/indexers/Indexers4.ql b/csharp/ql/test/library-tests/indexers/Indexers4.ql index 5eeb3808a53..08d693e9489 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers4.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers4.ql @@ -6,6 +6,6 @@ import csharp from Class c where - c.hasQualifiedName("Indexers.BitArray") and + c.hasQualifiedName("Indexers", "BitArray") and count(Indexer i | i.getDeclaringType() = c) = 1 select c diff --git a/csharp/ql/test/library-tests/indexers/Indexers5.ql b/csharp/ql/test/library-tests/indexers/Indexers5.ql index f264e130711..3e21cdd53cc 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers5.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers5.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.BitArray") and + i.getDeclaringType().hasQualifiedName("Indexers", "BitArray") and i.getType() instanceof BoolType and i.isPublic() and i.isReadWrite() diff --git a/csharp/ql/test/library-tests/indexers/Indexers6.ql b/csharp/ql/test/library-tests/indexers/Indexers6.ql index 148a896e515..9b33dd67126 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers6.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers6.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.BitArray") and + i.getDeclaringType().hasQualifiedName("Indexers", "BitArray") and i.getType() instanceof BoolType and i.getGetter().hasBody() and i.getSetter().hasBody() diff --git a/csharp/ql/test/library-tests/indexers/Indexers7.ql b/csharp/ql/test/library-tests/indexers/Indexers7.ql index 74dc80fa624..3c93f94ef9a 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers7.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers7.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.Grid") and + i.getDeclaringType().hasQualifiedName("Indexers", "Grid") and i.getType() instanceof IntType and i.getDimension() = 2 select i diff --git a/csharp/ql/test/library-tests/indexers/Indexers8.ql b/csharp/ql/test/library-tests/indexers/Indexers8.ql index abaf258fafe..f3fdfa9b0fe 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers8.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers8.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.Grid") and + i.getDeclaringType().hasQualifiedName("Indexers", "Grid") and i.getType() instanceof IntType and i.getParameter(0).getName() = "c" and i.getParameter(0).getType() instanceof CharType diff --git a/csharp/ql/test/library-tests/indexers/Indexers9.ql b/csharp/ql/test/library-tests/indexers/Indexers9.ql index a50719af912..5999bd14791 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers9.ql +++ b/csharp/ql/test/library-tests/indexers/Indexers9.ql @@ -6,7 +6,7 @@ import csharp from Indexer i where - i.getDeclaringType().hasQualifiedName("Indexers.Grid") and + i.getDeclaringType().hasQualifiedName("Indexers", "Grid") and i.getType() instanceof IntType and i.getParameter(1).getName() = "col" and i.getParameter(1).getType() instanceof IntType diff --git a/csharp/ql/test/library-tests/methods/Parameters1.ql b/csharp/ql/test/library-tests/methods/Parameters1.ql index d4b1939bfe7..c28a724198c 100644 --- a/csharp/ql/test/library-tests/methods/Parameters1.ql +++ b/csharp/ql/test/library-tests/methods/Parameters1.ql @@ -7,7 +7,7 @@ import csharp from Method m where m.hasName("Swap") and - m.getDeclaringType().hasQualifiedName("Methods.TestRef") and + m.getDeclaringType().hasQualifiedName("Methods", "TestRef") and m.getParameter(0).isRef() and m.getParameter(0).hasName("x") and m.getParameter(0).getType() instanceof IntType and diff --git a/csharp/ql/test/library-tests/methods/Parameters2.ql b/csharp/ql/test/library-tests/methods/Parameters2.ql index eb992f2c7f0..15b1471f1c5 100644 --- a/csharp/ql/test/library-tests/methods/Parameters2.ql +++ b/csharp/ql/test/library-tests/methods/Parameters2.ql @@ -7,7 +7,7 @@ import csharp from Method m where m.hasName("Divide") and - m.getDeclaringType().hasQualifiedName("Methods.TestOut") and + m.getDeclaringType().hasQualifiedName("Methods", "TestOut") and m.getParameter(0).isValue() and m.getParameter(0).hasName("x") and m.getParameter(0).getType() instanceof IntType and diff --git a/csharp/ql/test/library-tests/methods/Parameters3.ql b/csharp/ql/test/library-tests/methods/Parameters3.ql index 0c69218be58..8f286d7ee7e 100644 --- a/csharp/ql/test/library-tests/methods/Parameters3.ql +++ b/csharp/ql/test/library-tests/methods/Parameters3.ql @@ -7,7 +7,7 @@ import csharp from Method m where m.hasName("Write") and - m.getDeclaringType().hasQualifiedName("Methods.Console") and + m.getDeclaringType().hasQualifiedName("Methods", "Console") and m.getParameter(0).isValue() and m.getParameter(0).hasName("fmt") and m.getParameter(0).getType() instanceof StringType and diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces1.ql b/csharp/ql/test/library-tests/namespaces/Namespaces1.ql index 0a1e1e965b7..92fe438894b 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces1.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces1.ql @@ -6,7 +6,7 @@ import csharp from Namespace n where - n.hasQualifiedName("N1.N2") and + n.hasQualifiedName("N1", "N2") and n.getAClass().hasName("A") and n.getAClass().hasName("B") select n diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces10.ql b/csharp/ql/test/library-tests/namespaces/Namespaces10.ql index c45a49cbd39..135067040a4 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces10.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces10.ql @@ -6,11 +6,11 @@ import csharp from Namespace n, UnboundGenericClass ga, Class a where - n.hasQualifiedName("R1") and + n.hasQualifiedName("", "R1") and ga.hasQualifiedName("R1", "A<>") and ga.getATypeParameter().hasName("T") and ga.getNamespace() = n and - a.hasQualifiedName("R1.A") and + a.hasQualifiedName("R1", "A") and n.getAClass() = a and n.getAClass() = ga select n, ga, a diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces11.ql b/csharp/ql/test/library-tests/namespaces/Namespaces11.ql index 3aea83ac0cf..8f8453ad18e 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces11.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces11.ql @@ -6,7 +6,7 @@ import csharp from UsingNamespaceDirective u where - u.getParentNamespaceDeclaration().getNamespace().hasQualifiedName("S3") and - u.getImportedNamespace().hasQualifiedName("S1.S2") and + u.getParentNamespaceDeclaration().getNamespace().hasQualifiedName("", "S3") and + u.getImportedNamespace().hasQualifiedName("S1", "S2") and u.getFile().getBaseName() = "namespaces.cs" select u diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces12.ql b/csharp/ql/test/library-tests/namespaces/Namespaces12.ql index 73d66435b9d..5cc9dd3e643 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces12.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces12.ql @@ -7,6 +7,6 @@ import csharp from UsingNamespaceDirective u where u.getFile().getBaseName() = "namespaces.cs" and - u.getImportedNamespace().hasQualifiedName("System.Collections.Generic") and + u.getImportedNamespace().hasQualifiedName("System.Collections", "Generic") and not exists(u.getParentNamespaceDeclaration()) select u diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces2.ql b/csharp/ql/test/library-tests/namespaces/Namespaces2.ql index f176ad89d3d..0cebeb2eb7b 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces2.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces2.ql @@ -6,7 +6,7 @@ import csharp from Namespace n where - n.hasQualifiedName("M1.M2") and + n.hasQualifiedName("M1", "M2") and n.getAClass().hasName("A") and n.getAClass().hasName("B") select n diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces3.ql b/csharp/ql/test/library-tests/namespaces/Namespaces3.ql index 60acfc8bce5..0ecf971f3fe 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces3.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces3.ql @@ -6,7 +6,7 @@ import csharp from Namespace n where - n.hasQualifiedName("P1.P2") and + n.hasQualifiedName("P1", "P2") and n.getAClass().hasName("A") and n.getAClass().hasName("B") and n.getAStruct().hasName("S") and diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces4.ql b/csharp/ql/test/library-tests/namespaces/Namespaces4.ql index 81313001412..738a4c1966f 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces4.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces4.ql @@ -6,7 +6,7 @@ import csharp from Namespace n, Class a, Class b where - n.hasQualifiedName("M1.M2") and + n.hasQualifiedName("M1", "M2") and a = n.getAClass() and a.hasName("A") and a.isPublic() and diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces5.ql b/csharp/ql/test/library-tests/namespaces/Namespaces5.ql index 95c51ca1e37..aae2d671b2b 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces5.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces5.ql @@ -6,6 +6,6 @@ import csharp from Namespace n where - n.hasQualifiedName("Empty") and + n.hasQualifiedName("", "Empty") and not exists(n.getATypeDeclaration()) select n diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces6.ql b/csharp/ql/test/library-tests/namespaces/Namespaces6.ql index d89e2a998fa..27539b59f7e 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces6.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces6.ql @@ -6,9 +6,9 @@ import csharp from Namespace n, Namespace p where - n.hasQualifiedName("Q1.Q2") and + n.hasQualifiedName("Q1", "Q2") and n.hasName("Q2") and p = n.getParentNamespace() and p.hasName("Q1") and - p.hasQualifiedName("Q1") + p.hasQualifiedName("", "Q1") select p, n diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces7.ql b/csharp/ql/test/library-tests/namespaces/Namespaces7.ql index 4593ddef8c4..6822aacf1ef 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces7.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces7.ql @@ -6,7 +6,7 @@ import csharp from Namespace n, Class b, Class a where - n.hasQualifiedName("Q3") and + n.hasQualifiedName("", "Q3") and a.hasQualifiedName("Q1.Q2", "A") and b.hasName("B") and b.getNamespace() = n and diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces8.ql b/csharp/ql/test/library-tests/namespaces/Namespaces8.ql index 870f0c397b1..312fb960c91 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces8.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces8.ql @@ -6,7 +6,7 @@ import csharp from Namespace n, Class c, Class a where - n.hasQualifiedName("Q3") and + n.hasQualifiedName("", "Q3") and a.hasQualifiedName("Q1.Q2", "A") and c.hasName("C") and c.getNamespace() = n and diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces9.ql b/csharp/ql/test/library-tests/namespaces/Namespaces9.ql index 253e74ddfd6..ec380123d61 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces9.ql +++ b/csharp/ql/test/library-tests/namespaces/Namespaces9.ql @@ -10,5 +10,5 @@ where a.getATypeParameter().hasName("T") and a.getANestedType() = b and b.getName() = "B" and - b.hasQualifiedName("R1.A<>+B") + b.hasQualifiedName("R1", "A<>+B") select a, b diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes1.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes1.ql index 411ff0b664f..57b667876a5 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes1.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes1.ql @@ -6,8 +6,8 @@ import csharp from Class c, Struct s where - c.hasQualifiedName("NestedTypes.Base") and - s.hasQualifiedName("NestedTypes.Base+S") and + c.hasQualifiedName("NestedTypes", "Base") and + s.hasQualifiedName("NestedTypes", "Base+S") and s = c.getANestedType() and s.(NestedType).isProtected() and c.isPublic() diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes2.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes2.ql index 0432b5e4303..b3be4723dff 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes2.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes2.ql @@ -6,8 +6,8 @@ import csharp from Class c, Interface i where - c.hasQualifiedName("NestedTypes.Base") and - i.hasQualifiedName("NestedTypes.Base+I") and + c.hasQualifiedName("NestedTypes", "Base") and + i.hasQualifiedName("NestedTypes", "Base+I") and i.(NestedType).isPrivate() and i = c.getANestedType() select c, i diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes3.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes3.ql index d636c18b6d3..c3b216e23a2 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes3.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes3.ql @@ -6,8 +6,8 @@ import csharp from Class c, DelegateType d where - c.hasQualifiedName("NestedTypes.Base") and - d.hasQualifiedName("NestedTypes.Base+MyDelegate") and + c.hasQualifiedName("NestedTypes", "Base") and + d.hasQualifiedName("NestedTypes", "Base+MyDelegate") and d.(NestedType).isPrivate() and d = c.getANestedType() select c, d diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes4.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes4.ql index e52c9149db1..bfdb3a441e4 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes4.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes4.ql @@ -6,9 +6,9 @@ import csharp from Class base, Class derived, Class nested where - base.hasQualifiedName("NestedTypes.Base") and - derived.hasQualifiedName("NestedTypes.Derived") and - nested.hasQualifiedName("NestedTypes.Derived+Nested") and + base.hasQualifiedName("NestedTypes", "Base") and + derived.hasQualifiedName("NestedTypes", "Derived") and + nested.hasQualifiedName("NestedTypes", "Derived+Nested") and nested.getNamespace().hasName("NestedTypes") and derived.getBaseClass() = base and derived.isInternal() and diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes5.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes5.ql index d7a71757724..7585b923594 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes5.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes5.ql @@ -6,9 +6,9 @@ import csharp from Class base, Class derived, Class nested where - base.hasQualifiedName("NestedTypes.Base") and - derived.hasQualifiedName("NestedTypes.Derived") and - nested.hasQualifiedName("NestedTypes.Derived+Nested") and + base.hasQualifiedName("NestedTypes", "Base") and + derived.hasQualifiedName("NestedTypes", "Derived") and + nested.hasQualifiedName("NestedTypes", "Derived+Nested") and nested.getNamespace().hasName("NestedTypes") and nested.getDeclaringType() = derived select base, derived, nested diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes6.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes6.ql index 40c3337d643..ca2c3aadb89 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes6.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes6.ql @@ -6,7 +6,7 @@ import csharp from UnboundGenericClass o, UnboundGenericClass i where - o.hasQualifiedName("NestedTypes.Outer<>") and - i.hasQualifiedName("NestedTypes.Outer<>+Inner<>") and + o.hasQualifiedName("NestedTypes", "Outer<>") and + i.hasQualifiedName("NestedTypes", "Outer<>+Inner<>") and i = o.getANestedType() select o, i diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes7.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes7.ql index b8a58417789..750e2c72b01 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes7.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes7.ql @@ -6,8 +6,8 @@ import csharp from UnboundGenericClass o, UnboundGenericClass i where - o.hasQualifiedName("NestedTypes.Outer2<>") and - i.hasQualifiedName("NestedTypes.Outer2<>+Inner2<>") and + o.hasQualifiedName("NestedTypes", "Outer2<>") and + i.hasQualifiedName("NestedTypes", "Outer2<>+Inner2<>") and i = o.getANestedType() and i.getTypeParameter(0).getName() = o.getTypeParameter(0).getName() select o, i diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes8.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes8.ql index b854068b1e9..cc7fe1475a1 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes8.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes8.ql @@ -6,8 +6,8 @@ import csharp from ConstructedClass o, ConstructedClass i where - o.hasQualifiedName("NestedTypes.Outer") and - i.hasQualifiedName("NestedTypes.Outer+Inner") and + o.hasQualifiedName("NestedTypes", "Outer") and + i.hasQualifiedName("NestedTypes", "Outer+Inner") and i = o.getANestedType() and o.getTypeArgument(0) instanceof IntType and i.getTypeArgument(0) instanceof StringType diff --git a/csharp/ql/test/library-tests/nestedtypes/NestedTypes9.ql b/csharp/ql/test/library-tests/nestedtypes/NestedTypes9.ql index 2b926ce8ec6..75874018b87 100644 --- a/csharp/ql/test/library-tests/nestedtypes/NestedTypes9.ql +++ b/csharp/ql/test/library-tests/nestedtypes/NestedTypes9.ql @@ -6,8 +6,8 @@ import csharp from UnboundGenericClass o, ConstructedClass i where - o.hasQualifiedName("NestedTypes.Outer<>") and - i.hasQualifiedName("NestedTypes.Outer<>+Inner") and + o.hasQualifiedName("NestedTypes", "Outer<>") and + i.hasQualifiedName("NestedTypes", "Outer<>+Inner") and i.getUnboundGeneric() = o.getANestedType() and i.getTypeArgument(0) instanceof StringType select o, i diff --git a/csharp/ql/test/library-tests/properties/Properties10.ql b/csharp/ql/test/library-tests/properties/Properties10.ql index 7f2fae74da5..b2f0ca08da2 100644 --- a/csharp/ql/test/library-tests/properties/Properties10.ql +++ b/csharp/ql/test/library-tests/properties/Properties10.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Y") and - p.getDeclaringType().hasQualifiedName("Properties.A") and + p.getDeclaringType().hasQualifiedName("Properties", "A") and p.isReadWrite() and not p.isAutoImplemented() and p.isVirtual() and diff --git a/csharp/ql/test/library-tests/properties/Properties11.ql b/csharp/ql/test/library-tests/properties/Properties11.ql index ca1696d6152..10c25532a36 100644 --- a/csharp/ql/test/library-tests/properties/Properties11.ql +++ b/csharp/ql/test/library-tests/properties/Properties11.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Y") and - p.getDeclaringType().hasQualifiedName("Properties.B") and + p.getDeclaringType().hasQualifiedName("Properties", "B") and p.isReadWrite() and // overrides a property that is readwrite not p.isAutoImplemented() and p.isOverride() and diff --git a/csharp/ql/test/library-tests/properties/Properties12.ql b/csharp/ql/test/library-tests/properties/Properties12.ql index a8334485efc..a23d9d1d87c 100644 --- a/csharp/ql/test/library-tests/properties/Properties12.ql +++ b/csharp/ql/test/library-tests/properties/Properties12.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("X") and - p.getDeclaringType().hasQualifiedName("Properties.B") and + p.getDeclaringType().hasQualifiedName("Properties", "B") and p.isReadOnly() and not p.isAutoImplemented() and p.isOverride() and diff --git a/csharp/ql/test/library-tests/properties/Properties13.ql b/csharp/ql/test/library-tests/properties/Properties13.ql index f0bf658d1f9..97f6139ecb0 100644 --- a/csharp/ql/test/library-tests/properties/Properties13.ql +++ b/csharp/ql/test/library-tests/properties/Properties13.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Z") and - p.getDeclaringType().hasQualifiedName("Properties.B") and + p.getDeclaringType().hasQualifiedName("Properties", "B") and p.isReadWrite() and not p.isAutoImplemented() and p.isOverride() and diff --git a/csharp/ql/test/library-tests/properties/Properties14.ql b/csharp/ql/test/library-tests/properties/Properties14.ql index c6c3568e1b8..226dc003f18 100644 --- a/csharp/ql/test/library-tests/properties/Properties14.ql +++ b/csharp/ql/test/library-tests/properties/Properties14.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Count") and - p.getDeclaringType().hasQualifiedName("System.Collections.Generic.List<>") and + p.getDeclaringType().hasQualifiedName("System.Collections.Generic", "List<>") and not p.isAutoImplemented() and not p.isStatic() and p.isPublic() and diff --git a/csharp/ql/test/library-tests/properties/Properties15.ql b/csharp/ql/test/library-tests/properties/Properties15.ql index af729d49275..2f71f77aec7 100644 --- a/csharp/ql/test/library-tests/properties/Properties15.ql +++ b/csharp/ql/test/library-tests/properties/Properties15.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Init") and - p.getDeclaringType().hasQualifiedName("Properties.Test") and + p.getDeclaringType().hasQualifiedName("Properties", "Test") and p.isWriteOnly() and not p.isAutoImplemented() and p.isStatic() and diff --git a/csharp/ql/test/library-tests/properties/Properties16.ql b/csharp/ql/test/library-tests/properties/Properties16.ql index 4ef2776d39f..5cf64128372 100644 --- a/csharp/ql/test/library-tests/properties/Properties16.ql +++ b/csharp/ql/test/library-tests/properties/Properties16.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Init") and - p.getDeclaringType().hasQualifiedName("Properties.Test") and + p.getDeclaringType().hasQualifiedName("Properties", "Test") and p.getSetter().getNumberOfParameters() = 1 and p.getSetter().getParameter(0) instanceof ImplicitAccessorParameter select p, p.getSetter().getParameter(0) diff --git a/csharp/ql/test/library-tests/properties/Properties4.ql b/csharp/ql/test/library-tests/properties/Properties4.ql index 89a0b03f5b4..ad8055a45f4 100644 --- a/csharp/ql/test/library-tests/properties/Properties4.ql +++ b/csharp/ql/test/library-tests/properties/Properties4.ql @@ -10,6 +10,6 @@ where p.isReadOnly() and p.isPublic() and p.getGetter().hasBody() and - p.getDeclaringType().hasQualifiedName("Properties.Counter") and + p.getDeclaringType().hasQualifiedName("Properties", "Counter") and not exists(p.getSetter()) select p, p.getGetter() diff --git a/csharp/ql/test/library-tests/properties/Properties5.ql b/csharp/ql/test/library-tests/properties/Properties5.ql index 7c86e26a5c4..0e5291ae236 100644 --- a/csharp/ql/test/library-tests/properties/Properties5.ql +++ b/csharp/ql/test/library-tests/properties/Properties5.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("X") and - p.getDeclaringType().hasQualifiedName("Properties.Point") and + p.getDeclaringType().hasQualifiedName("Properties", "Point") and p.isReadWrite() and p.isPublic() and exists(p.getGetter()) and diff --git a/csharp/ql/test/library-tests/properties/Properties6.ql b/csharp/ql/test/library-tests/properties/Properties6.ql index 3e81cdc04e2..5ede824b59e 100644 --- a/csharp/ql/test/library-tests/properties/Properties6.ql +++ b/csharp/ql/test/library-tests/properties/Properties6.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Y") and - p.getDeclaringType().hasQualifiedName("Properties.Point") and + p.getDeclaringType().hasQualifiedName("Properties", "Point") and p.isReadWrite() and p.isPublic() and p.isAutoImplemented() diff --git a/csharp/ql/test/library-tests/properties/Properties7.ql b/csharp/ql/test/library-tests/properties/Properties7.ql index 8ad1f8a37e3..f31c29d1ec8 100644 --- a/csharp/ql/test/library-tests/properties/Properties7.ql +++ b/csharp/ql/test/library-tests/properties/Properties7.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("X") and - p.getDeclaringType().hasQualifiedName("Properties.ReadOnlyPoint") and + p.getDeclaringType().hasQualifiedName("Properties", "ReadOnlyPoint") and p.isReadWrite() and p.isPublic() and p.isAutoImplemented() and diff --git a/csharp/ql/test/library-tests/properties/Properties8.ql b/csharp/ql/test/library-tests/properties/Properties8.ql index eeb6bd41dc2..4033ea92484 100644 --- a/csharp/ql/test/library-tests/properties/Properties8.ql +++ b/csharp/ql/test/library-tests/properties/Properties8.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("X") and - p.getDeclaringType().hasQualifiedName("Properties.A") and + p.getDeclaringType().hasQualifiedName("Properties", "A") and p.isReadOnly() and p.isVirtual() select p diff --git a/csharp/ql/test/library-tests/properties/Properties9.ql b/csharp/ql/test/library-tests/properties/Properties9.ql index 5b22b9d5394..e55ffafa131 100644 --- a/csharp/ql/test/library-tests/properties/Properties9.ql +++ b/csharp/ql/test/library-tests/properties/Properties9.ql @@ -7,7 +7,7 @@ import csharp from Property p where p.hasName("Z") and - p.getDeclaringType().hasQualifiedName("Properties.A") and + p.getDeclaringType().hasQualifiedName("Properties", "A") and p.isReadWrite() and not p.isAutoImplemented() and p.isAbstract() and diff --git a/csharp/ql/test/library-tests/types/Types17.ql b/csharp/ql/test/library-tests/types/Types17.ql index 80c0b783a53..c73a26c7b26 100644 --- a/csharp/ql/test/library-tests/types/Types17.ql +++ b/csharp/ql/test/library-tests/types/Types17.ql @@ -6,5 +6,5 @@ import csharp from Enum e -where e.getQualifiedName() = "Types.Enum" +where e.hasQualifiedName("Types", "Enum") select e diff --git a/csharp/ql/test/library-tests/types/Types18.ql b/csharp/ql/test/library-tests/types/Types18.ql index 3d15ac88d27..34b11bb0bfb 100644 --- a/csharp/ql/test/library-tests/types/Types18.ql +++ b/csharp/ql/test/library-tests/types/Types18.ql @@ -6,5 +6,5 @@ import csharp from Struct s -where s.getQualifiedName() = "Types.Struct" +where s.hasQualifiedName("Types", "Struct") select s diff --git a/csharp/ql/test/library-tests/types/Types19.ql b/csharp/ql/test/library-tests/types/Types19.ql index e0352d8b547..27f7f02f0c1 100644 --- a/csharp/ql/test/library-tests/types/Types19.ql +++ b/csharp/ql/test/library-tests/types/Types19.ql @@ -6,5 +6,5 @@ import csharp from Class c -where c.getQualifiedName() = "Types.Class" +where c.hasQualifiedName("Types", "Class") select c diff --git a/csharp/ql/test/library-tests/types/Types20.ql b/csharp/ql/test/library-tests/types/Types20.ql index a7bc8e81474..ae9c38c8d08 100644 --- a/csharp/ql/test/library-tests/types/Types20.ql +++ b/csharp/ql/test/library-tests/types/Types20.ql @@ -6,5 +6,5 @@ import csharp from Interface i -where i.getQualifiedName() = "Types.Interface" +where i.hasQualifiedName("Types", "Interface") select i diff --git a/csharp/ql/test/library-tests/types/Types21.ql b/csharp/ql/test/library-tests/types/Types21.ql index b111f959d20..2e5f54991f6 100644 --- a/csharp/ql/test/library-tests/types/Types21.ql +++ b/csharp/ql/test/library-tests/types/Types21.ql @@ -6,5 +6,5 @@ import csharp from UnboundGenericClass c -where c.getQualifiedName() = "Types.GenericClass<>" +where c.hasQualifiedName("Types", "GenericClass<>") select c diff --git a/csharp/ql/test/library-tests/types/Types22.ql b/csharp/ql/test/library-tests/types/Types22.ql index b539167d66a..059831abf21 100644 --- a/csharp/ql/test/library-tests/types/Types22.ql +++ b/csharp/ql/test/library-tests/types/Types22.ql @@ -6,5 +6,5 @@ import csharp from UnboundGenericInterface c -where c.getQualifiedName() = "Types.GenericInterface<>" +where c.hasQualifiedName("Types", "GenericInterface<>") select c diff --git a/csharp/ql/test/library-tests/types/Types23.ql b/csharp/ql/test/library-tests/types/Types23.ql index 05a214086ab..229f86eb584 100644 --- a/csharp/ql/test/library-tests/types/Types23.ql +++ b/csharp/ql/test/library-tests/types/Types23.ql @@ -6,5 +6,5 @@ import csharp from UnboundGenericStruct c -where c.getQualifiedName() = "Types.GenericStruct<>" +where c.hasQualifiedName("Types", "GenericStruct<>") select c diff --git a/csharp/ql/test/library-tests/types/Types30.ql b/csharp/ql/test/library-tests/types/Types30.ql index 1d00aa27e10..b79a8d47344 100644 --- a/csharp/ql/test/library-tests/types/Types30.ql +++ b/csharp/ql/test/library-tests/types/Types30.ql @@ -7,7 +7,7 @@ import csharp from UnboundGenericClass c, TypeParameter p1, TypeParameter p2 where - c.getQualifiedName() = "Types.Map<,>" and + c.hasQualifiedName("Types", "Map<,>") and c.getTypeParameter(0) = p1 and c.getTypeParameter(1) = p2 and p1.getName() = "U" and diff --git a/csharp/ql/test/library-tests/types/Types31.ql b/csharp/ql/test/library-tests/types/Types31.ql index 204123bb779..07b68b63d2a 100644 --- a/csharp/ql/test/library-tests/types/Types31.ql +++ b/csharp/ql/test/library-tests/types/Types31.ql @@ -11,6 +11,6 @@ where m.getReturnType() = t and t.getTypeArgument(0) = arg1 and t.getTypeArgument(1) = arg2 and - arg1.getQualifiedName() = "System.String" and - arg2.getQualifiedName() = "Types.Class" + arg1.hasQualifiedName("System", "String") and + arg2.hasQualifiedName("Types", "Class") select t, arg1.toString(), arg2 diff --git a/csharp/ql/test/library-tests/types/Types34.ql b/csharp/ql/test/library-tests/types/Types34.ql index 12e2dc0920b..36aa7eba142 100644 --- a/csharp/ql/test/library-tests/types/Types34.ql +++ b/csharp/ql/test/library-tests/types/Types34.ql @@ -7,5 +7,5 @@ where t1.getDimension() = 2 and t1.getElementType() = t2 and t2.getDimension() = 1 and - t2.getElementType().(Class).getQualifiedName() = "Types.Class" + t2.getElementType().(Class).hasQualifiedName("Types", "Class") select t1, t2 diff --git a/csharp/ql/test/library-tests/types/Types35.ql b/csharp/ql/test/library-tests/types/Types35.ql index 3f55fcd8197..40a6808f7a5 100644 --- a/csharp/ql/test/library-tests/types/Types35.ql +++ b/csharp/ql/test/library-tests/types/Types35.ql @@ -10,5 +10,5 @@ where m.getName() = "NullableType" and m.getReturnType() = t1 and t1.getUnderlyingType() = t2 and - t2.getQualifiedName() = "Types.Struct" + t2.hasQualifiedName("Types", "Struct") select t1 diff --git a/csharp/ql/test/library-tests/types/Types36.ql b/csharp/ql/test/library-tests/types/Types36.ql index cf9c897996b..a201312b805 100644 --- a/csharp/ql/test/library-tests/types/Types36.ql +++ b/csharp/ql/test/library-tests/types/Types36.ql @@ -1,5 +1,5 @@ import csharp from Interface i -where i.hasQualifiedName("System.Collections.IEnumerable") -select i.getQualifiedName() +where i.hasQualifiedName("System.Collections", "IEnumerable") +select "System.Collections.IEnumerable" diff --git a/csharp/ql/test/qlpack.yml b/csharp/ql/test/qlpack.yml index 3e526fe5800..b0ce8ef1920 100644 --- a/csharp/ql/test/qlpack.yml +++ b/csharp/ql/test/qlpack.yml @@ -4,6 +4,4 @@ dependencies: codeql/csharp-all: ${workspace} codeql/csharp-queries: ${workspace} extractor: csharp -dataExtensions: - - library-tests/dataflow/external-models/ext/*.model.yml tests: . diff --git a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected index 17a51125c4c..397d77531b2 100644 --- a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected +++ b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected @@ -19,6 +19,10 @@ | ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. | | ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. | | ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. | +| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. | +| ConstantIsNullOrEmpty.cs:54:21:54:45 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. | | ConstantNullCoalescingLeftHandOperand.cs:11:24:11:34 | access to constant NULL_OBJECT | Expression is never 'null'. | | ConstantNullCoalescingLeftHandOperand.cs:12:24:12:27 | null | Expression is always 'null'. | | ConstantWhileCondition.cs:12:20:12:32 | ... == ... | Condition always evaluates to 'true'. | diff --git a/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs new file mode 100644 index 00000000000..5cad2e818ab --- /dev/null +++ b/csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantIsNullOrEmpty.cs @@ -0,0 +1,60 @@ +using System.Threading.Tasks; + +namespace ConstantIsNullOrEmpty +{ + internal class Program + { + static void Main(string[] args) + { + { + if (string.IsNullOrEmpty(nameof(args))) // bad: always false + { + } + + string? x = null; + if (string.IsNullOrEmpty(x)) // would be nice... bad: always true + { + } + + string y = ""; + if (string.IsNullOrEmpty(y)) // would be nice... bad: always true + { + } + + if (args[1] != null) + y = "b"; + if (string.IsNullOrEmpty(y)) // good: non-constant + { + } + + string z = " "; + if (string.IsNullOrEmpty(z)) // would be nice... bad: always false + { + } + + string a = "a"; + if (string.IsNullOrEmpty(a)) // would be nice... bad: always false + { + } + + if (args[1] != null) + a = ""; + if (string.IsNullOrEmpty(a)) // good: non-constant + { + } + + if (string.IsNullOrEmpty(null)) // bad: always true + { + } + + if (string.IsNullOrEmpty("")) // bad: always true + { + } + + if (string.IsNullOrEmpty(" ")) // bad: always false + { + } + } + } + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected index 2f3c3bbb4a6..396d766c3e6 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/AssemblyPathInjection.expected @@ -1 +1,11 @@ -| Test.cs:10:36:10:46 | access to local variable libraryName | This assembly path depends on a $@. | Test.cs:7:26:7:48 | access to property QueryString | user-provided value | +edges +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:7:26:7:63 | access to indexer : String | +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:10:36:10:46 | access to local variable libraryName | +| Test.cs:7:26:7:63 | access to indexer : String | Test.cs:10:36:10:46 | access to local variable libraryName | +nodes +| Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | +| Test.cs:7:26:7:63 | access to indexer : String | semmle.label | access to indexer : String | +| Test.cs:10:36:10:46 | access to local variable libraryName | semmle.label | access to local variable libraryName | +subpaths +#select +| Test.cs:10:36:10:46 | access to local variable libraryName | Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | Test.cs:10:36:10:46 | access to local variable libraryName | This assembly path depends on a $@. | Test.cs:7:26:7:48 | access to property QueryString : NameValueCollection | user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected b/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected index 7c3a2a7339c..10cb82ff67e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-321/HardcodedSymmetricEncryptionKey/HardcodedSymmetricEncryptionKey.expected @@ -1,7 +1,40 @@ -| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | This hard-coded $@ is used in symmetric algorithm in Decryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | -| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" | symmetric key | +edges +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | +| HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | +| HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | +nodes +| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | semmle.label | array creation of type Byte[] | +| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | semmle.label | array creation of type Byte[] | +| HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | semmle.label | array creation of type Byte[] : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:39:28:116 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | semmle.label | "Hello, world: here is a very bad way to create a key" : String | +| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | semmle.label | access to local variable d | +| HardcodedSymmetricEncryptionKey.cs:36:37:36:37 | access to local variable d : Byte[] | semmle.label | access to local variable d : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:41:50:41:50 | access to local variable c : Byte[] | semmle.label | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:44:51:44:69 | access to local variable byteArrayFromString : Byte[] | semmle.label | access to local variable byteArrayFromString : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:50:35:50:35 | access to local variable c : Byte[] | semmle.label | access to local variable c : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:59:64:59:71 | password : Byte[] | semmle.label | password : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | semmle.label | access to parameter password | +| HardcodedSymmetricEncryptionKey.cs:103:57:103:59 | key : Byte[] | semmle.label | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | semmle.label | access to parameter key | +| HardcodedSymmetricEncryptionKey.cs:112:63:112:65 | key : Byte[] | semmle.label | key : Byte[] | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | semmle.label | access to parameter key | +subpaths +#select +| HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:17:21:17:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:22:23:22:99 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:31:21:31:21 | access to local variable d | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:68:87:68:94 | access to parameter password | This hard-coded $@ is used in symmetric algorithm in Decryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:108:23:108:25 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Key property assignment | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] : Byte[] | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:25:21:25:97 | array creation of type Byte[] | symmetric key | +| HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" : String | HardcodedSymmetricEncryptionKey.cs:121:87:121:89 | access to parameter key | This hard-coded $@ is used in symmetric algorithm in Encryptor(rgbKey, IV) | HardcodedSymmetricEncryptionKey.cs:28:62:28:115 | "Hello, world: here is a very bad way to create a key" | symmetric key | diff --git a/csharp/ql/test/query-tests/Telemetry/LibraryUsage/ExternalLibraryUsage.expected b/csharp/ql/test/query-tests/Telemetry/LibraryUsage/ExternalLibraryUsage.expected index e64b827f137..7b5c4c57661 100644 --- a/csharp/ql/test/query-tests/Telemetry/LibraryUsage/ExternalLibraryUsage.expected +++ b/csharp/ql/test/query-tests/Telemetry/LibraryUsage/ExternalLibraryUsage.expected @@ -1,2 +1,2 @@ -| System.Private.CoreLib.dll#System | 5 | -| System.Private.CoreLib.dll#System.Collections.Generic | 2 | +| System | 5 | +| System.Collections.Generic | 2 | diff --git a/csharp/ql/test/query-tests/Telemetry/LibraryUsage/SupportedExternalTaint.expected b/csharp/ql/test/query-tests/Telemetry/LibraryUsage/SupportedExternalTaint.expected index e9be925c286..b386e4acb38 100644 --- a/csharp/ql/test/query-tests/Telemetry/LibraryUsage/SupportedExternalTaint.expected +++ b/csharp/ql/test/query-tests/Telemetry/LibraryUsage/SupportedExternalTaint.expected @@ -1 +1 @@ -| System.Private.CoreLib.dll#System.Collections.Generic#List<>.Add(T) | 2 | +| System.Collections.Generic#List<>.Add(T) | 2 | diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs new file mode 100644 index 00000000000..6231ff6f61c --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Web; + +public class SupportedExternalApis +{ + public void M1() + { + var l = new List(); // Uninteresting parameterless constructor + var o = new object(); // Uninteresting parameterless constructor + l.Add(o); // Has flow summary + l.Add(o); // Has flow summary + } + + public void M2() + { + var d0 = new DateTime(); // Uninteresting parameterless constructor + var next0 = d0.AddYears(30); // Has no flow summary, supported as negative summary + + var d1 = new DateTime(2000, 1, 1); // Interesting constructor, supported as negative summary + var next1 = next0.AddDays(3); // Has no flow summary, supported as negative summary + var next2 = next1.AddYears(5); // Has no flow summary, supported as negative summary + } + + public void M3() + { + var guid1 = Guid.Parse("{12345678-1234-1234-1234-123456789012}"); // Has no flow summary, supported as negative summary + } + + public void M4() + { + var o = new object(); // Uninteresting parameterless constructor + var response = new HttpResponse(); // Uninteresting parameterless constructor + response.AddHeader("header", "value"); // Unsupported + response.AppendHeader("header", "value"); // Unsupported + response.Write(o); // Known sink + response.WriteFile("filename"); // Known sink + response.Write(o); // Known sink + } + + public void M5() + { + var l1 = Console.ReadLine(); // Known source + var l2 = Console.ReadLine(); // Known source + Console.SetError(Console.Out); // Has no flow summary, supported as negative summary + var x = Console.Read(); // Known source + } +} diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..f8b6feafb92 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,11 @@ +| System#Console.ReadLine() | 2 | +| System#DateTime.AddYears(System.Int32) | 2 | +| System.Collections.Generic#List<>.Add(T) | 2 | +| System.Web#HttpResponse.Write(System.Object) | 2 | +| System#Console.Read() | 1 | +| System#Console.SetError(System.IO.TextWriter) | 1 | +| System#Console.get_Out() | 1 | +| System#DateTime.AddDays(System.Double) | 1 | +| System#DateTime.DateTime(System.Int32,System.Int32,System.Int32) | 1 | +| System#Guid.Parse(System.String) | 1 | +| System.Web#HttpResponse.WriteFile(System.String) | 1 | diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options new file mode 100644 index 00000000000..9bbedebd7a2 --- /dev/null +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /r:System.Collections.Specialized.dll +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected b/csharp/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected index b85e33ddae7..b3acebc02e0 100644 --- a/csharp/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected @@ -1,2 +1,2 @@ -| System.Web.cs#System.Web#HttpResponse.Write(System.Object) | 2 | -| System.Web.cs#System.Web#HttpResponse.WriteFile(System.String) | 1 | +| System.Web#HttpResponse.Write(System.Object) | 2 | +| System.Web#HttpResponse.WriteFile(System.String) | 1 | diff --git a/csharp/ql/test/query-tests/Telemetry/SupportedExternalSources/SupportedExternalSources.expected b/csharp/ql/test/query-tests/Telemetry/SupportedExternalSources/SupportedExternalSources.expected index 0f125b04b94..93c23f159a6 100644 --- a/csharp/ql/test/query-tests/Telemetry/SupportedExternalSources/SupportedExternalSources.expected +++ b/csharp/ql/test/query-tests/Telemetry/SupportedExternalSources/SupportedExternalSources.expected @@ -1,2 +1,2 @@ -| System.Console.dll#System#Console.ReadLine() | 2 | -| System.Console.dll#System#Console.Read() | 1 | +| System#Console.ReadLine() | 2 | +| System#Console.Read() | 1 | diff --git a/csharp/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref b/csharp/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref deleted file mode 100644 index c24d124c0b2..00000000000 --- a/csharp/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/model-generator/CaptureNegativeSummaryModels.ql \ No newline at end of file diff --git a/csharp/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.expected b/csharp/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.expected similarity index 100% rename from csharp/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.expected rename to csharp/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.expected diff --git a/csharp/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref b/csharp/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref new file mode 100644 index 00000000000..cb6ef7faa65 --- /dev/null +++ b/csharp/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref @@ -0,0 +1 @@ +utils/model-generator/CaptureNeutralModels.ql \ No newline at end of file diff --git a/csharp/ql/test/utils/model-generator/dataflow/NoSummaries.cs b/csharp/ql/test/utils/model-generator/dataflow/NoSummaries.cs index 112857f504e..b2c21b57917 100644 --- a/csharp/ql/test/utils/model-generator/dataflow/NoSummaries.cs +++ b/csharp/ql/test/utils/model-generator/dataflow/NoSummaries.cs @@ -131,4 +131,15 @@ public class CollectionFlow { return a; } -} \ No newline at end of file +} + +// A neutral model should not be created for a parameterless constructor. +public class ParameterlessConstructor +{ + public bool IsInitialized; + + public ParameterlessConstructor() + { + IsInitialized = true; + } +} diff --git a/csharp/scripts/create-extractor-pack.sh b/csharp/scripts/create-extractor-pack.sh new file mode 100755 index 00000000000..dbbe8219a02 --- /dev/null +++ b/csharp/scripts/create-extractor-pack.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -eux + +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + platform="linux64" + dotnet_platform="linux-x64" +elif [[ "$OSTYPE" == "darwin"* ]]; then + platform="osx64" + dotnet_platform="osx-x64" +else + echo "Unknown OS" + exit 1 +fi + +rm -rf extractor-pack +mkdir -p extractor-pack +mkdir -p extractor-pack/tools/${platform} + +function dotnet_publish { + dotnet publish --self-contained --configuration Release --runtime ${dotnet_platform} -p:RuntimeFrameworkVersion=6.0.4 $1 --output extractor-pack/tools/${platform} +} + +dotnet_publish extractor/Semmle.Extraction.CSharp.Standalone +dotnet_publish extractor/Semmle.Extraction.CSharp.Driver +dotnet_publish autobuilder/Semmle.Autobuild.CSharp + +cp -r codeql-extractor.yml tools/* downgrades tools ql/lib/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme.stats extractor-pack/ diff --git a/docs/codeql/README.rst b/docs/codeql/README.rst index d27fe2189d2..a07d15c27e1 100644 --- a/docs/codeql/README.rst +++ b/docs/codeql/README.rst @@ -42,9 +42,10 @@ For more information, see Building and previewing the CodeQL documentation ************************************************ -To build and preview the documentation and training presentations locally, you need to -install Sphinx 1.7.9. More recent versions of Sphinx do not work with hieroglyph, -the Sphinx extension that we use to generate HTML slides, as explained below. +To build and preview the documentation and training presentations locally, you need to +install Sphinx 1.7.9 using Python 2 (for example: `pip install sphinx==1.7.9`). +More recent versions of Sphinx do not work with hieroglyph, +the Sphinx extension that we use to generate HTML slides, as explained below. For installation options, see https://github.com/sphinx-doc/sphinx. diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index 72fb979c563..bc9924b740a 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -312,7 +312,7 @@ For more information, see "`Using CodeQL query packs in the CodeQL action `__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements. +Many codebases have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements. Example finding unreachable statements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ Example finding unreachable statements where not exists(s.getAFlowNode()) select s -➤ `See this in the query console on LGTM.com `__. This query gives fewer results, but most of the projects have some unreachable nodes. These are also highlighted by the standard "Unreachable code" query. For more information, see `Unreachable code `__ on LGTM.com. +This query should give fewer results. You can also find unreachable code using the standard "Unreachable code" query. For more information, see `Unreachable code `__. The ``BasicBlock`` class ------------------------ @@ -114,7 +114,7 @@ Example finding mutually exclusive blocks within the same function ) select b1, b2 -➤ `See this in the query console on LGTM.com `__. This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python `." +This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python `." Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst index 75309842ad5..2eccdf5e103 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst @@ -5,6 +5,10 @@ Analyzing data flow in Java You can use CodeQL to track the flow of data through a Java program to its use. +.. include:: ../reusables/kotlin-beta-note.rst + +.. include:: ../reusables/kotlin-java-differences.rst + About this article ------------------ diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst index f5128e5eafd..2ad5fc925f0 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst @@ -97,11 +97,9 @@ Python has builtin functionality for reading and writing files, such as the func call = API::moduleImport("os").getMember("open").getACall() select call.getArg(0) -➤ `See this in the query console on LGTM.com `__. Two of the demo projects make use of this low-level API. - Notice the use of the ``API`` module for referring to library functions. For more information, see ":doc:`Using API graphs in Python `." -Unfortunately this will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument: +Unfortunately this query will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument: .. code-block:: ql @@ -115,9 +113,7 @@ Unfortunately this will only give the expression in the argument, not the values DataFlow::localFlow(expr, call.getArg(0)) select call, expr -➤ `See this in the query console on LGTM.com `__. Many expressions flow to the same call. - -We see that we get several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node: +Typically, you will see several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node: .. code-block:: ql @@ -160,9 +156,9 @@ As an alternative, we can ask more directly that ``expr`` is a local source of t expr = call.getArg(0).getALocalSource() select call, expr -➤ `See this in the query console on LGTM.com `__. All these three queries give identical results. We now mostly have one expression per call. +These three queries all give identical results. We now mostly have one expression per call. -We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting, as in the second case). +We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting). We might want to make the source more specific, for example a parameter to a function or method. This query finds instances where a parameter is used as the name when opening a file: @@ -178,7 +174,7 @@ We might want to make the source more specific, for example a parameter to a fun DataFlow::localFlow(p, call.getArg(0)) select call, p -➤ `See this in the query console on LGTM.com `__. Very few results now; these could feasibly be inspected manually. +For most codebases, this will return only a few results and these could be inspected manually. Using the exact name supplied via the parameter may be too strict. If we want to know if the parameter influences the file name, we can use taint tracking instead of data flow. This query finds calls to ``os.open`` where the filename is derived from a parameter: @@ -194,7 +190,7 @@ Using the exact name supplied via the parameter may be too strict. If we want to TaintTracking::localTaint(p, call.getArg(0)) select call, p -➤ `See this in the query console on LGTM.com `__. Now we get more results and in more projects. +Typically, this finds more results. Global data flow ---------------- @@ -369,8 +365,6 @@ This data flow configuration tracks data flow from environment variables to open select fileOpen, "This call to 'os.open' uses data from $@.", environment, "call to 'os.getenv'" -➤ `Running this in the query console on LGTM.com `__ unsurprisingly yields no results in the demo projects. - Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/annotations-in-java.rst b/docs/codeql/codeql-language-guides/annotations-in-java.rst index 3439fb6ff0e..38f30e238f0 100644 --- a/docs/codeql/codeql-language-guides/annotations-in-java.rst +++ b/docs/codeql/codeql-language-guides/annotations-in-java.rst @@ -51,7 +51,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att anntp.hasQualifiedName("java.lang", "SuppressWarnings") select ann, ann.getValue("value") -➤ `See the full query in the query console on LGTM.com `__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above. +If the codebase you are analyzing uses the ``@SuppressWarnings`` annotation, you can check the ``value``\ s of the annotation element returned by the query. They should use the ``"rawtypes"`` value described above. As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``: @@ -66,8 +66,6 @@ As another example, this query finds all annotation types that only have a singl ) select anntp -➤ `See the full query in the query console on LGTM.com `__. - Example: Finding missing ``@Override`` annotations -------------------------------------------------- @@ -124,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano not overriding.getAnAnnotation() instanceof OverrideAnnotation select overriding, "Method overrides another method, but does not have an @Override annotation." -➤ `See this in the query console on LGTM.com `__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available. +In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available. Example: Finding calls to deprecated methods -------------------------------------------- @@ -237,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation select call, "This call invokes a deprecated method." -➤ `See this in the query console on LGTM.com `__. It's fairly common for projects to contain calls to methods that appear to be deprecated. +It's fairly common for projects to contain calls to methods that appear to be deprecated. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst index 91cbab4cd07..47a762b4d3e 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst @@ -3,7 +3,9 @@ Basic query for C and C++ code ============================== -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat if (error) { } -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **C/C++** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import cpp``. .. code-block:: ql - import cpp - from IfStmt ifstmt, BlockStmt block where ifstmt.getThen() = block and block.getNumStmt() = 0 select ifstmt, "This 'if' statement is redundant." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-cpp-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-cpp-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer. - - The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -120,7 +93,7 @@ In this case, identifying the ``if`` statement with the empty ``then`` branch as To exclude ``if`` statements that have an ``else`` branch: -#. Extend the ``where`` clause to include the following extra condition: +#. Edit your query and extend the ``where`` clause to include the following extra condition: .. code-block:: ql @@ -134,14 +107,24 @@ To exclude ``if`` statements that have an ``else`` branch: block.getNumStmt() = 0 and not ifstmt.hasElse() -#. Click **Run**. +#. Re-run the query. There are now fewer results because ``if`` statements with an ``else`` branch are no longer reported. -➤ `See this in the query console `__ - Further reading --------------- .. include:: ../reusables/cpp-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: C/C++ + +.. |language-code| replace:: ``cpp`` + +.. |example-url| replace:: https://github.com/protocolbuffers/protobuf + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-cpp.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. diff --git a/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst index f61edbac0f9..18c76ed4f52 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst @@ -3,7 +3,9 @@ Basic query for C# code ======================= -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat if (error) { } -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **C#** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import csharp``. .. code-block:: ql - import csharp - from IfStmt ifstmt, BlockStmt block where ifstmt.getThen() = block and block.isEmpty() select ifstmt, "This 'if' statement is redundant." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. + .. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-csharp-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-csharp-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer. - - The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,14 +112,23 @@ To exclude ``if`` statements that have an ``else`` branch: block.isEmpty() and not exists(ifstmt.getElse()) -#. Click **Run**. +#. Re-run the query. There are now fewer results because ``if`` statements with an ``else`` branch are no longer included. -➤ `See this in the query console `__ - Further reading --------------- .. include:: ../reusables/csharp-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions +.. |language-text| replace:: C# + +.. |language-code| replace:: ``csharp`` + +.. |example-url| replace:: https://github.com/PowerShell/PowerShell + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-csharp.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. diff --git a/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst index 15ae9caee7d..0e23dc16922 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst @@ -3,7 +3,9 @@ Basic query for Go code ======================= -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -22,29 +24,17 @@ This is problematic because the receiver argument is passed by value, not by ref For further information on using methods on values or pointers in Go, see the `Go FAQ `__. -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Go** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import go``. .. code-block:: ql - import go - from Method m, Variable recv, Write w, Field f where recv = m.getReceiver() and @@ -52,34 +42,17 @@ Running the query not recv.getType() instanceof PointerType select w, "This update to " + f + " has no effect, because " + recv + " is not a pointer." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-go-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``w`` column to open the file and highlight the matching location. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-go-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to ``w``, which is the location in the source code where the receiver ``recv`` is modified. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``w`` column to view it in the code viewer. - - The matching ``w`` is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -140,14 +113,24 @@ To exclude these values: not recv.getType() instanceof PointerType and not exists(ReturnStmt ret | ret.getExpr() = recv.getARead().asExpr()) -#. Click **Run**. +#. Re-run the query. There are now fewer results because value methods that return their receiver variable are no longer reported. -➤ `See this in the query console `__ - Further reading --------------- .. include:: ../reusables/go-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: Go + +.. |language-code| replace:: ``go`` + +.. |example-url| replace:: https://github.com/go-gorm/gorm + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-go.png + +.. |result-col-1| replace:: The first column corresponds to ``w``, which is the location in the source code where the receiver ``recv`` is modified. diff --git a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst index bc721ce9371..a7d783804b9 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst @@ -1,100 +1,90 @@ .. _basic-query-for-java-code: -Basic query for Java code -========================= +Basic query for Java and Kotlin code +==================================== -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- -The query we're going to run performs a basic search of the code for ``if`` statements that are redundant, in the sense that they have an empty then branch. For example, code such as: +The query we're going to run searches for inefficient tests for empty strings. For example, Java code such as: .. code-block:: java - if (error) { } + public class TestJava { + void myJavaFun(String s) { + boolean b = s.equals(""); + } + } -Running the query ------------------ +or Kotlin code such as: -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +.. code-block:: kotlin -#. Click the project in the search results. + void myKotlinFun(s: String) { + var b = s.equals("") + } -#. Click **Query this project**. +In either case, replacing ``s.equals("")`` with ``s.isEmpty()`` +would be more efficient. - This opens the query console. (For information about using this, see `Using the query console `__.) +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst - .. pull-quote:: +Running a quick query +--------------------- - Note +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Java** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import java``. .. code-block:: ql - import java + from MethodAccess ma + where + ma.getMethod().hasName("equals") and + ma.getArgument(0).(StringLiteral).getValue() = "" + select ma, "This comparison to empty string is inefficient, use isEmpty() instead." - from IfStmt ifstmt, Block block - where ifstmt.getThen() = block and - block.getNumStmt() = 0 - select ifstmt, "This 'if' statement is redundant." + Note that CodeQL treats Java and Kotlin as part of the same language, so even though this query starts with ``import java``, it will work for both Java and Kotlin code. - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. + .. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-java-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``ma`` column to view the ``.equals`` expression in the code viewer. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-java-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer. - - The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ After the initial ``import`` statement, this simple query comprises three parts that serve similar purposes to the FROM, WHERE, and SELECT parts of an SQL query. -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| Query part | Purpose | Details | -+===============================================================+===================================================================================================================+========================================================================================================================+ -| ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``from IfStmt ifstmt, Block block`` | Defines the variables for the query. | We use: | -| | Declarations are of the form: | | -| | `` `` | - an ``IfStmt`` variable for ``if`` statements | -| | | - a ``Block`` variable for the then block | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``where ifstmt.getThen() = block and block.getNumStmt() = 0`` | Defines a condition on the variables. | ``ifstmt.getThen() = block`` relates the two variables. The block must be the ``then`` branch of the ``if`` statement. | -| | | | -| | | ``block.getNumStmt() = 0`` states that the block must be empty (that is, it contains no statements). | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``select ifstmt, "This 'if' statement is redundant."`` | Defines what to report for each match. | Reports the resulting ``if`` statement with a string that explains the problem. | -| | | | -| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | | -| | ``select , ""`` | | -+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| Query part | Purpose | Details | ++==================================================================================================+===================================================================================================================+===================================================================================================+ +| ``import java`` | Imports the standard CodeQL libraries for Java and Kotlin. | Every query begins with one or more ``import`` statements. | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``from MethodAccess ma`` | Defines the variables for the query. | We use: | +| | Declarations are of the form: | | +| | `` `` | - a ``MethodAccess`` variable for call expressions | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``where ma.getMethod().hasName("equals") and ma.getArgument(0).(StringLiteral).getValue() = ""`` | Defines a condition on the variables. | ``ma.getMethod().hasName("equals")`` restricts ``ma`` to only calls to methods call ``equals``. | +| | | | +| | | ``ma.getArgument(0).(StringLiteral).getValue() = ""`` says the argument must be literal ``""``. | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ +| ``select ma, "This comparison to empty string is inefficient, use isEmpty() instead."`` | Defines what to report for each match. | Reports the resulting ``.equals`` expression with a string that explains the problem. | +| | | | +| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | | +| | ``select , ""`` | | ++--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+ Extend the query ---------------- @@ -104,44 +94,51 @@ Query writing is an inherently iterative process. You write a simple query and t Remove false positive results ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Browsing the results of our basic query shows that it could be improved. Among the results you are likely to find examples of ``if`` statements with an ``else`` branch, where an empty ``then`` branch does serve a purpose. For example: +Browsing the results of our basic query shows that it could be improved. For example, you may find results for code like: .. code-block:: java - if (...) { - ... - } else if ("-verbose".equals(option)) { - // nothing to do - handled earlier - } else { - error("unrecognized option"); - } + public class TestJava { + void myJavaFun(Object o) { + boolean b = o.equals(""); + } + } -In this case, identifying the ``if`` statement with the empty ``then`` branch as redundant is a false positive. One solution to this is to modify the query to ignore empty ``then`` branches if the ``if`` statement has an ``else`` branch. - -To exclude ``if`` statements that have an ``else`` branch: +In this case, it is not possible to simply use ``o.isEmpty()`` instead, as ``o`` has type ``Object`` rather than ``String``. One solution to this is to modify the query to only return results where the expression being tested has type ``String``: #. Extend the where clause to include the following extra condition: .. code-block:: ql - and not exists(ifstmt.getElse()) + ma.getQualifier().getType() instanceof TypeString The ``where`` clause is now: .. code-block:: ql - where ifstmt.getThen() = block and - block.getNumStmt() = 0 and - not exists(ifstmt.getElse()) + where + ma.getQualifier().getType() instanceof TypeString and + ma.getMethod().hasName("equals") and + ma.getArgument(0).(StringLiteral).getValue() = "" -#. Click **Run**. +#. Re-run the query. - There are now fewer results because ``if`` statements with an ``else`` branch are no longer included. - -➤ `See this in the query console `__ + There are now fewer results because ``.equals`` expressions with different types are no longer included. Further reading --------------- .. include:: ../reusables/java-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: Java + +.. |language-code| replace:: ``java`` + +.. |example-url| replace:: https://github.com/apache/activemq + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-java.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``ma`` and is linked to the location in the source code of the project where ``ma`` occurs. \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst index 123336d699e..90cb3f77cfd 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst @@ -3,7 +3,9 @@ Basic query for JavaScript code =============================== -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -12,62 +14,33 @@ In JavaScript, any expression can be turned into an expression statement. While The query you will run finds instances of this problem. The query searches for expressions ``e`` that are pure—that is, their evaluation does not lead to any side effects—but appear as an expression statement. -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **JavaScript** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import javascript``. .. code-block:: ql - import javascript - from Expr e where e.isPure() and e.getParent() instanceof ExprStmt select e, "This expression has no effect." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click one of the links in the ``e`` column to open the file and highlight the matching expression. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``e`` and is linked to the location in the source code of the project where ``e`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click one of the links in the ``e`` column to view the expression in the code viewer. - - The matching statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -119,11 +92,14 @@ To remove directives from the results: e.getParent() instanceof ExprStmt and not e.getParent() instanceof Directive -#. Click **Run**. +#. Re-run the query. There are now fewer results as ``use strict`` directives are no longer reported. -The improved query finds several results on the example project including `this result `__: +The improved query finds several results on the example project including the result below: + +.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-1.png + :align: center .. code-block:: javascript @@ -136,3 +112,15 @@ Further reading .. include:: ../reusables/javascript-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: JavaScript/TypeScript + +.. |language-code| replace:: ``javascript`` + +.. |example-url| replace:: https://github.com/ajaxorg/ace + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-js.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``e`` and is linked to the location in the source code of the project where ``e`` occurs. \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst index f8424b00d4e..a6df8b453d9 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst @@ -3,7 +3,9 @@ Basic query for Python code =========================== -Learn to write and run a simple CodeQL query using LGTM. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat if error: pass -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Python** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import python``. .. code-block:: ql - import python - from If ifstmt, Stmt pass where pass = ifstmt.getStmt(0) and pass instanceof Pass select ifstmt, "This 'if' statement is redundant." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-python-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-python-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer. - - The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -133,14 +106,24 @@ To exclude ``if`` statements that have an ``else`` branch: pass instanceof Pass and not exists(ifstmt.getOrelse()) -#. Click **Run**. +#. Re-run the query. There are now fewer results because ``if`` statements with an ``else`` branch are no longer included. -➤ `See this in the query console `__ - Further reading --------------- .. include:: ../reusables/python-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: Python + +.. |language-code| replace:: ``python`` + +.. |example-url| replace:: https://github.com/saltstack/salt + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-python.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/basic-query-for-ruby-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-ruby-code.rst index 4acc85e6a85..a74fe802ef2 100644 --- a/docs/codeql/codeql-language-guides/basic-query-for-ruby-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-ruby-code.rst @@ -3,7 +3,9 @@ Basic query for Ruby code ========================= -Learn to write and run a simple CodeQL query. +Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension. + +.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst About the query --------------- @@ -15,24 +17,14 @@ The query we're going to run performs a basic search of the code for ``if`` expr if error # Handle the error -Running the query ------------------ +.. include:: ../reusables/vs-code-basic-instructions/find-database.rst -#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching `__. +Running a quick query +--------------------- -#. Click the project in the search results. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst -#. Click **Query this project**. - - This opens the query console. (For information about using this, see `Using the query console `__.) - - .. pull-quote:: - - Note - - Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Ruby** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list. - -#. Copy the following query into the text box in the query console: +#. In the quick query tab, delete the content and paste in the following query. .. code-block:: ql @@ -40,37 +32,20 @@ Running the query from IfExpr ifexpr where - not exists(ifexpr.getThen()) + not exists(ifexpr.getThen()) select ifexpr, "This 'if' expression is redundant." - LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query. +.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst -#. Click **Run**. +.. image:: ../images/codeql-for-visual-studio-code/basic-ruby-query-results-1.png + :align: center - The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: +If any matching code is found, click a link in the ``ifexpr`` column to open the file and highlight the matching ``if`` statement. - .. image:: ../images/query-progress.png - :align: center +.. image:: ../images/codeql-for-visual-studio-code/basic-ruby-query-results-2.png + :align: center - .. pull-quote:: - - Note - - Your query is always run against the most recently analyzed commit to the selected project. - - The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifexpr`` and is linked to the location in the source code of the project where ``ifexpr`` occurs. The second column is the alert message. - - ➤ `Example query results `__ - - .. pull-quote:: - - Note - - An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results. - -#. If any matching code is found, click a link in the ``ifexpr`` column to view the ``if`` statement in the code viewer. - - The matching ``if`` expression is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code. +.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst About the query structure ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -131,14 +106,24 @@ To exclude ``if`` statements that have an ``else`` branch: not exists(ifexpr.getThen()) and not exists(ifexpr.getElse()) -#. Click **Run**. +#. Re-run the query. There are now fewer results because ``if`` expressions with an ``else`` branch are no longer included. -➤ `See this in the query console `__ - Further reading --------------- .. include:: ../reusables/ruby-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions + +.. |language-text| replace:: Ruby + +.. |language-code| replace:: ``ruby`` + +.. |example-url| replace:: https://github.com/discourse/discourse + +.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-ruby.png + +.. |result-col-1| replace:: The first column corresponds to the expression ``ifexpr`` and is linked to the location in the source code of the project where ``ifexpr`` occurs. diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp.rst b/docs/codeql/codeql-language-guides/codeql-for-cpp.rst index 8acd450ecd7..4e5e53d8cb2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-cpp.rst @@ -21,7 +21,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat hash-consing-and-value-numbering -- :doc:`Basic query for C and C++ code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for C and C++ code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for C and C++ `: When analyzing C or C++ code, you can use the large collection of classes in the CodeQL library for C and C++. diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp.rst b/docs/codeql/codeql-language-guides/codeql-for-csharp.rst index e327cb177ee..9b692094841 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-csharp.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-csharp.rst @@ -12,7 +12,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-csharp analyzing-data-flow-in-csharp -- :doc:`Basic query for C# code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for C# code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for C# `: When you're analyzing a C# program, you can make use of the large collection of classes in the CodeQL library for C#. diff --git a/docs/codeql/codeql-language-guides/codeql-for-go.rst b/docs/codeql/codeql-language-guides/codeql-for-go.rst index be81a19f1a8..0eaefbb5922 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-go.rst @@ -13,7 +13,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat abstract-syntax-tree-classes-for-working-with-go-programs modeling-data-flow-in-go-libraries -- :doc:`Basic query for Go code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Go code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Go `: When you're analyzing a Go program, you can make use of the large collection of classes in the CodeQL library for Go. diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 53489bc5207..aa10f481592 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -1,9 +1,16 @@ .. _codeql-for-java: -CodeQL for Java -=============== +CodeQL for Java and Kotlin +========================== -Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java codebases. +Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java and Kotlin codebases. + +.. include:: ../reusables/kotlin-beta-note.rst + + +.. pull-quote:: Enabling Kotlin support + + CodeQL treats Java and Kotlin as parts of the same language, so to enable Kotlin support you should enable ``java`` as a language. .. toctree:: :hidden: @@ -19,7 +26,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat working-with-source-locations abstract-syntax-tree-classes-for-working-with-java-programs -- :doc:`Basic query for Java code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Java code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Java `: When analyzing Java code, you can use the large collection of classes in the CodeQL library for Java. diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index ce6651acb79..11a4c5e456c 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -18,7 +18,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs data-flow-cheat-sheet-for-javascript -- :doc:`Basic query for JavaScript code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for JavaScript code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for JavaScript `: When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript. diff --git a/docs/codeql/codeql-language-guides/codeql-for-python.rst b/docs/codeql/codeql-language-guides/codeql-for-python.rst index 15b0c4a84f8..3b639e9cdf2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-python.rst @@ -16,7 +16,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat expressions-and-statements-in-python analyzing-control-flow-in-python -- :doc:`Basic query for Python code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Python code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Python `: When you need to analyze a Python program, you can make use of the large collection of classes in the CodeQL library for Python. diff --git a/docs/codeql/codeql-language-guides/codeql-for-ruby.rst b/docs/codeql/codeql-language-guides/codeql-for-ruby.rst index 82d13cf410e..f36df2496bf 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-ruby.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-ruby.rst @@ -14,7 +14,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat analyzing-data-flow-in-ruby using-api-graphs-in-ruby -- :doc:`Basic query for Ruby code `: Learn to write and run a simple CodeQL query using LGTM. +- :doc:`Basic query for Ruby code `: Learn to write and run a simple CodeQL query. - :doc:`CodeQL library for Ruby `: When you're analyzing a Ruby program, you can make use of the large collection of classes in the CodeQL library for Ruby. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst index c4072ad55b2..319afdf29c0 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst @@ -70,7 +70,7 @@ For example, the following query finds all variables of type ``int`` in the prog pt.hasName("int") select v -➤ `See this in the query console on LGTM.com `__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``. +You're likely to get many results when you run this query because most projects contain many variables of type ``int``. Reference types are also categorized according to their declaration scope: @@ -87,7 +87,7 @@ For instance, this query finds all top-level types whose name is not the same as where tl.getName() != tl.getCompilationUnit().getName() select tl -➤ `See this in the query console on LGTM.com `__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code. +You will typically see this pattern in the source code of a repository, with many more instances in the files referenced by the source code. Several more specialized classes are available as well: @@ -109,7 +109,7 @@ As an example, we can write a query that finds all nested classes that directly where nc.getASupertype() instanceof TypeObject select nc -➤ `See this in the query console on LGTM.com `__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly. +You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly. Generics ~~~~~~~~ @@ -143,8 +143,6 @@ For instance, we could use the following query to find all parameterized instanc pt.getSourceDeclaration() = map select pt -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files. - In general, generic types may restrict which types a type parameter can be bound to. For instance, a type of maps from strings to numbers could be declared as follows: .. code-block:: java @@ -166,8 +164,6 @@ As an example, the following query finds all type variables with type bound ``Nu tb.getType().hasQualifiedName("java.lang", "Number") select tv -➤ `See this in the query console on LGTM.com `__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *hibernate/hibernate-orm* and *apache/hadoop* projects all contained examples of this pattern. - For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``: .. code-block:: ql @@ -179,8 +175,6 @@ For dealing with legacy code that is unaware of generics, every generic type has rt.getSourceDeclaration().hasQualifiedName("java.util", "Map") select v -➤ `See this in the query console on LGTM.com `__. Many projects have variables of raw type ``Map``. - For example, in the following code snippet this query would find ``m1``, but not ``m2``: .. code-block:: java @@ -230,7 +224,7 @@ For example, the following query finds all expressions whose parents are ``retur where e.getParent() instanceof ReturnStmt select e -➤ `See this in the query console on LGTM.com `__. Many projects have examples of ``return`` statements with child expressions. +Many projects have examples of ``return`` statements with child expressions. Therefore, if the program contains a return statement ``return x + y;``, this query will return ``x + y``. @@ -244,7 +238,7 @@ As another example, the following query finds statements whose parent is an ``if where s.getParent() instanceof IfStmt select s -➤ `See this in the query console on LGTM.com `__. Many projects have examples of ``if`` statements with child statements. +Many projects have examples of ``if`` statements with child statements. This query will find both ``then`` branches and ``else`` branches of all ``if`` statements in the program. @@ -258,8 +252,6 @@ Finally, here is a query that finds method bodies: where s.getParent() instanceof Method select s -➤ `See this in the query console on LGTM.com `__. Most projects have many method bodies. - As these examples show, the parent node of an expression is not always an expression: it may also be a statement, for example, an ``IfStmt``. Similarly, the parent node of a statement is not always a statement: it may also be a method or a constructor. To capture this, the QL Java library provides two abstract class ``ExprParent`` and ``StmtParent``, the former representing any node that may be the parent node of an expression, and the latter any node that may be the parent node of a statement. For more information on working with AST classes, see the :doc:`article on overflow-prone comparisons in Java `. @@ -278,7 +270,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t from Constructor c select c.getAnAnnotation() -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated. +You may see examples where annotations are used to suppress warnings or to mark code as deprecated. These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors: @@ -292,7 +284,7 @@ These annotations are represented by class ``Annotation``. An annotation is simp anntp.hasQualifiedName("java.lang", "Deprecated") select ann -➤ `See this in the query console on LGTM.com `__. Only constructors with the ``@Deprecated`` annotation are reported this time. +Only constructors with the ``@Deprecated`` annotation are reported this time. For more information on working with annotations, see the :doc:`article on annotations `. @@ -307,7 +299,7 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a jdoc = f.getDoc().getJavadoc() select jdoc -➤ `See this in the query console on LGTM.com `__. You can see this pattern in many projects. +You can see this pattern in many projects. Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields: @@ -321,8 +313,6 @@ Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocEle at.getParent+() = jdoc select at -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields. - .. pull-quote:: Note @@ -349,7 +339,7 @@ For example, the following query finds methods with a `cyclomatic complexity 40 select m -➤ `See this in the query console on LGTM.com `__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test. +Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test. Call graph ---------- @@ -369,8 +359,6 @@ We can use predicate ``Call.getCallee`` to find out which method or constructor m.hasName("println") select c -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all include many calls to methods of this name. - Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So we can find methods and constructors that are never called using this query: .. code-block:: ql @@ -381,7 +369,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So where not exists(c.getAReference()) select c -➤ `See this in the query console on LGTM.com `__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." +Codebases often have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph `." For more information about callables and calls, see the :doc:`article on the call graph `. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst index e9070cc493b..8c9c6d8cffa 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -43,7 +43,7 @@ Textual level At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text. -Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. In particular, databases on LGTM (also known as "snapshots") do not normally include textual information. +Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. Files and folders ^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ For example, the following query computes, for each folder, the number of JavaSc from Folder d select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js") -➤ `See this in the query console on LGTM.com `__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. +When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. Locations ^^^^^^^^^ @@ -138,7 +138,7 @@ As an example of a query operating entirely on the lexical level, consider the f where comma.getNextToken() instanceof CommaToken select comma, "Omitted array elements are bad style." -➤ `See this in the query console on LGTM.com `__. If the query returns no results, this pattern isn't used in the projects that you analyzed. +If the query returns no results, this pattern isn't used in the projects that you analyzed. You can use predicate ``Locatable.getFirstToken()`` and ``Locatable.getLastToken()`` to access the first and last token (if any) belonging to an element with a source location. @@ -179,8 +179,6 @@ As an example of a query using only lexical information, consider the following from HtmlLineComment c select c, "Do not use HTML comments." -➤ `See this in the query console on LGTM.com `__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments. - Syntactic level ~~~~~~~~~~~~~~~ @@ -230,7 +228,7 @@ The `TopLevel `__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets. - Functions ^^^^^^^^^ @@ -373,8 +369,6 @@ As an example, here is a query that finds all expression closures: where fe.getBody() instanceof Expr select fe, "Use arrow expressions instead of expression closures." -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects. - As another example, this query finds functions that have two parameters that bind the same variable: .. code-block:: ql @@ -388,8 +382,6 @@ As another example, this query finds functions that have two parameters that bin p.getAVariable() = q.getAVariable() select fun, "This function has two parameters that bind the same variable." -➤ `See this in the query console on LGTM.com `__. None of the LGTM.com demo projects has functions where two parameters bind the same variable. - Classes ^^^^^^^ @@ -444,7 +436,7 @@ Here is an example of a query to find declaration statements that declare the sa not ds.getTopLevel().isMinified() select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here" -➤ `See this in the query console on LGTM.com `__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing. +This is not a common problem, so you may not find any results in your own projects. Notice the use of ``not ... isMinified()`` here and in the next few queries. This excludes any results found in minified code. If you delete ``and not ds.getTopLevel().isMinified()`` and re-run the query, two results in minified code in the *meteor/meteor* project are reported. @@ -471,8 +463,6 @@ As an example of a query involving properties, consider the following query that not oe.getTopLevel().isMinified() select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here" -➤ `See this in the query console on LGTM.com `__. Many projects have a few instances of object expressions with two identically named properties. - Modules ^^^^^^^ @@ -537,7 +527,7 @@ As an example, consider the following query which finds distinct function declar not g.getTopLevel().isMinified() select f, g -➤ `See this in the query console on LGTM.com `__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. +Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. Control flow ~~~~~~~~~~~~ @@ -574,7 +564,7 @@ As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u not f.getStartBB().isLiveAtEntry(gv, _) select f, "This function uses " + gv + " like a local variable." -➤ `See this in the query console on LGTM.com `__. Many projects have some variables which look as if they were intended to be local. +Many projects have some variables which look as if they were intended to be local. Data flow ~~~~~~~~~ @@ -599,8 +589,6 @@ As an example, the following query finds definitions of local variables that are not exists (VarUse use | def = use.getADef()) select def, "Dead store of local variable." -➤ `See this in the query console on LGTM.com `__. Many projects have some examples of useless assignments to local variables. - SSA ^^^ @@ -642,8 +630,6 @@ For example, here is a query that finds all invocations of a method called ``sen send.getMethodName() = "send" select send -➤ `See this in the query console on LGTM.com `__. The query finds HTTP response sends in the `AMP HTML `__ project. - Note that the data flow modeling in this library is intraprocedural, that is, flow across function calls and returns is *not* modeled. Likewise, flow through object properties and global variables is not modeled. Type inference @@ -707,8 +693,6 @@ As an example of a call-graph-based query, here is a query to find invocations f not exists(invk.getACallee()) select invk, "Unable to find a callee for this invocation." -➤ `See this in the query console on LGTM.com `__ - Inter-procedural data flow ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -843,7 +827,7 @@ As an example of the use of these classes, here is a query that counts for every from NodeModule m select m, count(m.getAnImportedModule()) -➤ `See this in the query console on LGTM.com `__. When you analyze a project, for each module you can see how many other modules it imports. +When you analyze a project, for each module you can see how many other modules it imports. NPM ^^^ @@ -872,8 +856,6 @@ As an example of the use of these classes, here is a query that identifies unuse not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue()) select deps, "Unused dependency '" + name + "'." -➤ `See this in the query console on LGTM.com `__. It is not uncommon for projects to have some unused dependencies. - React ^^^^^ @@ -899,8 +881,6 @@ For example, here is a query to find SQL queries that use string concatenation ( where ss instanceof AddExpr select ss, "Use templating instead of string concatenation." -➤ `See this in the query console on LGTM.com `__, showing two (benign) results on `strong-arc `__. - Miscellaneous ~~~~~~~~~~~~~ @@ -965,8 +945,6 @@ As an example, here is a query that finds ``@param`` tags that do not specify th not exists(t.getName()) select t, "@param tag is missing name." -➤ `See this in the query console on LGTM.com `__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name. - For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation `__. JSX diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst index 204a6d22c3b..c1b392cc358 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst @@ -53,7 +53,7 @@ All scopes are basically a list of statements, although ``Scope`` classes have a where f.getScope() instanceof Function select f -➤ `See this in the query console on LGTM.com `__. Many projects have nested functions. +Many codebases use nested functions. Statement ^^^^^^^^^ @@ -95,7 +95,7 @@ As an example, to find expressions of the form ``a+2`` where the left is a simpl where bin.getLeft() instanceof Name and bin.getRight() instanceof Num select bin -➤ `See this in the query console on LGTM.com `__. Many projects include examples of this pattern. +Many codebases include examples of this pattern. Variable ^^^^^^^^ @@ -126,7 +126,7 @@ For our first example, we can find all ``finally`` blocks by using the ``Try`` c from Try t select t.getFinalbody() -➤ `See this in the query console on LGTM.com `__. Many projects include examples of this pattern. +Many codebases include examples of this pattern. 2. Finding ``except`` blocks that do nothing '''''''''''''''''''''''''''''''''''''''''''' @@ -157,7 +157,7 @@ Both forms are equivalent. Using the positive expression, the whole query looks where forall(Stmt s | s = ex.getAStmt() | s instanceof Pass) select ex -➤ `See this in the query console on LGTM.com `__. Many projects include pass-only ``except`` blocks. +Many codebases include pass-only ``except`` blocks. Summary ^^^^^^^ @@ -278,8 +278,6 @@ Using this predicate we can select the longest ``BasicBlock`` by selecting the ` where bb_length(b) = max(bb_length(_)) select b -➤ `See this in the query console on LGTM.com `__. When we ran it on the LGTM.com demo projects, the *openstack/nova* and *ytdl-org/youtube-dl* projects both contained source code results for this query. - .. pull-quote:: Note diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst index e729011a3e9..b1709bb05c5 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst @@ -123,8 +123,6 @@ Select expressions that cast a value to a type parameter: where assertion.getTypeAnnotation() = param.getLocalTypeName().getAnAccess() select assertion, "Cast to type parameter." -➤ `See this in the query console on LGTM.com `__. - Classes and interfaces ~~~~~~~~~~~~~~~~~~~~~~ @@ -179,7 +177,7 @@ Ambient nodes are mostly ignored by control flow and data flow analysis. The out Static type information ----------------------- -Static type information and global name binding is available for projects with "full" TypeScript extraction enabled. This option is enabled by default for projects on LGTM.com and when you create databases with the :ref:`CodeQL CLI `. +Static type information and global name binding is available for projects with "full" TypeScript extraction enabled. This option is enabled by default when you create databases with the :ref:`CodeQL CLI `. Basic usage ~~~~~~~~~~~ @@ -403,8 +401,6 @@ It is best to use `TypeName `__. - Find imported names that are used as both a type and a value: .. code-block:: ql @@ -416,8 +412,6 @@ Find imported names that are used as both a type and a value: and exists (VarAccess access | access.getVariable().getADeclaration() = spec.getLocal()) select spec, "Used as both variable and type" -➤ `See this in the query console on LGTM.com `__. - Namespace names ~~~~~~~~~~~~~~~ diff --git a/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst index 9bd057412f6..0ceacc3acd9 100644 --- a/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst @@ -165,8 +165,6 @@ Our starting point for the query is pairs of a base class and a derived class, c where derived.getABaseClass+() = base select base, derived, "The second class is derived from the first." -➤ `See this in the query console on LGTM.com `__ - Note that the transitive closure symbol ``+`` indicates that ``Class.getABaseClass()`` may be followed one or more times, rather than only accepting a direct base class. A lot of the results are uninteresting template parameters. You can remove those results by updating the ``where`` clause as follows: @@ -177,8 +175,6 @@ A lot of the results are uninteresting template parameters. You can remove those and not exists(base.getATemplateArgument()) and not exists(derived.getATemplateArgument()) -➤ `See this in the query console on LGTM.com `__ - Finding derived classes with destructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -196,8 +192,6 @@ Now we can extend the query to find derived classes with destructors, using the and d2 = derived.getDestructor() select base, derived, "The second class is derived from the first, and both have a destructor." -➤ `See this in the query console on LGTM.com `__ - Notice that getting the destructor implicitly asserts that one exists. As a result, this version of the query returns fewer results than before. Finding base classes where the destructor is not virtual @@ -216,11 +210,9 @@ Our last change is to use ``Function.isVirtual()`` to find cases where the base and not d1.isVirtual() select d1, "This destructor should probably be virtual." -➤ `See this in the query console on LGTM.com `__ - That completes the query. -There is a similar built-in `query `__ on LGTM.com that finds classes in a C/C++ project with virtual functions but no virtual destructor. You can take a look at the code for this query by clicking **Open in query console** at the top of that page. +There is a similar standard query `Non-virtual destructor in base class `__ that finds classes in a C/C++ project with virtual functions but no virtual destructor. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst index 48cca630660..32a16560bc3 100644 --- a/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst +++ b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst @@ -54,8 +54,6 @@ The ``global`` statement in Python declares a variable with a global (module-lev where g.getScope() instanceof Module select g -➤ `See this in the query console on LGTM.com `__. None of the demo projects on LGTM.com has a global statement that matches this pattern. - The line: ``g.getScope() instanceof Module`` ensures that the ``Scope`` of ``Global g`` is a ``Module``, rather than a class or function. Example finding 'if' statements with redundant branches @@ -81,7 +79,7 @@ To find statements like this that could be simplified we can write a query. and forall(Stmt p | p = l.getAnItem() | p instanceof Pass) select i -➤ `See this in the query console on LGTM.com `__. Many projects have some ``if`` statements that match this pattern. +Many codebases have some ``if`` statements that match this pattern. The line: ``(l = i.getBody() or l = i.getOrelse())`` restricts the ``StmtList l`` to branches of the ``if`` statement. @@ -150,8 +148,6 @@ We can check for these using a query. and cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal select cmp -➤ `See this in the query console on LGTM.com `__. Two of the demo projects on LGTM.com use this pattern: *saltstack/salt* and *openstack/nova*. - The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` checks that the first comparison operator is "is" and that the first comparator is a literal. .. pull-quote:: @@ -180,7 +176,7 @@ If there are duplicate keys in a Python dictionary, then the second key will ove and k1 != k2 and same_key(k1, k2) select k1, "Duplicate key in dict literal" -➤ `See this in the query console on LGTM.com `__. When we ran this query on LGTM.com, the source code of the *saltstack/salt* project contained an example of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. Two of the other demo projects on LGTM.com refer to duplicate dictionary keys in library files. For more information, see `Duplicate key in dict literal `__ on LGTM.com. +When we ran this query on some test codebases, we found examples of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. For more information, see `Duplicate key in dict literal `__. The supporting predicate ``same_key`` checks that the keys have the same identifier. Separating this part of the logic into a supporting predicate, instead of directly including it in the query, makes it easier to understand the query as a whole. The casts defined in the predicate restrict the expression to the type specified and allow predicates to be called on the type that is cast-to. For example: @@ -222,8 +218,6 @@ This basic query can be improved by checking that the one line of code is a Java and attr.getObject() = self and self.getId() = "self" select f, "This function is a Java-style getter." -➤ `See this in the query console on LGTM.com `__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters. - .. code-block:: ql ret = f.getStmt(0) and ret.getValue() = attr diff --git a/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst index d7adc22c2cd..c9515aca4c8 100644 --- a/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst @@ -23,8 +23,6 @@ In the following example we find instances of ``AssignExpr`` which assign the co where e.getRValue().getValue().toInt() = 0 select e, "Assigning the value 0 to something." -➤ `See this in the query console on LGTM.com `__ - The ``where`` clause in this example gets the expression on the right side of the assignment, ``getRValue()``, and compares it with zero. Notice that there are no checks to make sure that the right side of the assignment is an integer or that it has a value (that is, it is compile-time constant, rather than a variable). For expressions where either of these assumptions is wrong, the associated predicate simply does not return anything and the ``where`` clause will not produce a result. You could think of it as if there is an implicit ``exists(e.getRValue().getValue().toInt())`` at the beginning of this line. It is also worth noting that the query above would find this C code: @@ -33,7 +31,7 @@ It is also worth noting that the query above would find this C code: yPtr = NULL; -This is because the database contains a representation of the code base after the preprocessor transforms have run. This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the database. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers. For more information, see `Database generation `__ on LGTM.com. +This is because the database contains a representation of the code base after the preprocessor transforms have run. This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the database. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers. For more information, see `Database creation `__. Finding assignments of 0 to an integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -49,8 +47,6 @@ We can make the query more specific by defining a condition for the left side of and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType select e, "Assigning the value 0 to an integer." -➤ `See this in the query console on LGTM.com `__ - This checks that the left side of the assignment has a type that is some kind of integer. Note the call to ``Type.getUnspecifiedType()``. This resolves ``typedef`` types to their underlying types so that the query finds assignments like this one: .. code-block:: cpp @@ -109,8 +105,6 @@ Unfortunately this would not quite work, because the loop initialization is actu and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType select e, "Assigning the value 0 to an integer, inside a for loop initialization." -➤ `See this in the query console on LGTM.com `__ - Finding assignments of 0 within the loop body ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -127,8 +121,6 @@ We can find assignments inside the loop body using similar code with the predica and e.getLValue().getType().getUnderlyingType() instanceof IntegralType select e, "Assigning the value 0 to an integer, inside a for loop body." -➤ `See this in the query console on LGTM.com `__ - Note that we replaced ``e.getEnclosingStmt()`` with ``e.getEnclosingStmt().getParentStmt*()``, to find an assignment expression that is deeply nested inside the loop body. The transitive closure modifier ``*`` here indicates that ``Stmt.getParentStmt()`` may be followed zero or more times, rather than just once, giving us the statement, its parent statement, its parent's parent statement etc. Further reading diff --git a/docs/codeql/codeql-language-guides/functions-in-cpp.rst b/docs/codeql/codeql-language-guides/functions-in-cpp.rst index 84d72e5376a..34c99885c6a 100644 --- a/docs/codeql/codeql-language-guides/functions-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/functions-in-cpp.rst @@ -40,8 +40,6 @@ It might be more interesting to find functions that are not called, using the st where not exists(FunctionCall fc | fc.getTarget() = f) select f, "This function is never called." -➤ `See this in the query console on LGTM.com `__ - The new query finds functions that are not the target of any ``FunctionCall``—in other words, functions that are never called. You may be surprised by how many results the query finds. However, if you examine the results, you can see that many of the functions it finds are used indirectly. To create a query that finds only unused functions, we need to refine the query and exclude other ways of using a function. Excluding functions that are referenced with a function pointer @@ -58,13 +56,11 @@ You can modify the query to remove functions where a function pointer is used to and not exists(FunctionAccess fa | fa.getTarget() = f) select f, "This function is never called, or referenced with a function pointer." -➤ `See this in the query console on LGTM.com `__ - This query returns fewer results. However, if you examine the results then you can probably still find potential refinements. -For example, there is a more complicated LGTM `query `__ that finds unused static functions. To see the code for this query, click **Open in query console** at the top of the page. +For example, there is a more complicated standard query, `Unused static function `__, that finds unused static functions. - You can explore the definition of an element in the standard libraries and see what predicates are available. Use the keyboard **F3** button to open the definition of any element. Alternatively, hover over the element and click **Jump to definition** in the tooltip displayed. The library file is opened in a new tab with the definition highlighted. + You can explore the definition of an element in the standard libraries and see what predicates are available. Right-click the element to display the context menu, and click **Go to Definition**. The library file is opened in a new tab with the definition of the element highlighted. Finding a specific function --------------------------- @@ -80,8 +76,6 @@ This query uses ``Function`` and ``FunctionCall`` to find calls to the function and not fc.getArgument(1) instanceof StringLiteral select fc, "sprintf called with variable format string." -➤ `See this in the query console on LGTM.com `__ - This uses: - ``Declaration.getQualifiedName()`` to identify calls to the specific function ``sprintf``. @@ -89,7 +83,7 @@ This uses: Note that we could have used ``Declaration.getName()``, but ``Declaration.getQualifiedName()`` is a better choice because it includes the namespace. For example: ``getName()`` would return ``vector`` where ``getQualifiedName`` would return ``std::vector``. -The LGTM version of this query is considerably more complicated, but if you look carefully you will find that its structure is the same. See `Non-constant format string `__ and click **Open in query console** at the top of the page. +The published version of this query is considerably more complicated, but if you look carefully you will find that its structure is the same. See `Non-constant format string `__. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/functions-in-python.rst b/docs/codeql/codeql-language-guides/functions-in-python.rst index ab401f6c5e5..fbb4ff0d6e5 100644 --- a/docs/codeql/codeql-language-guides/functions-in-python.rst +++ b/docs/codeql/codeql-language-guides/functions-in-python.rst @@ -28,7 +28,7 @@ Using the member predicate ``Function.getName()``, we can list all of the getter where f.getName().matches("get%") select f, "This is a function called get..." -➤ `See this in the query console on LGTM.com `__. This query typically finds a large number of results. Usually, many of these results are for functions (rather than methods) which we are not interested in. +This query typically finds a large number of results. Usually, many of these results are for functions (rather than methods) which we are not interested in. Finding all methods called "get..." ----------------------------------- @@ -43,7 +43,7 @@ You can modify the query above to return more interesting results. As we are onl where f.getName().matches("get%") and f.isMethod() select f, "This is a method called get..." -➤ `See this in the query console on LGTM.com `__. This finds methods whose name starts with ``"get"``, but many of those are not the sort of simple getters we are interested in. +This finds methods whose name starts with ``"get"``, but many of those are not the sort of simple getters we are interested in. Finding one line methods called "get..." ---------------------------------------- @@ -59,7 +59,7 @@ We can modify the query further to include only methods whose body consists of a and count(f.getAStmt()) = 1 select f, "This function is (probably) a getter." -➤ `See this in the query console on LGTM.com `__. This query returns fewer results, but if you examine the results you can see that there are still refinements to be made. This is refined further in ":doc:`Expressions and statements in Python `." +This query returns fewer results, but if you examine the results you can see that there are still refinements to be made. This is refined further in ":doc:`Expressions and statements in Python `." Finding a call to a specific function ------------------------------------- @@ -74,8 +74,6 @@ This query uses ``Call`` and ``Name`` to find calls to the function ``eval`` - w where call.getFunc() = name and name.getId() = "eval" select call, "call to 'eval'." -➤ `See this in the query console on LGTM.com `__. Some of the demo projects on LGTM.com use this function. - The ``Call`` class represents calls in Python. The ``Call.getFunc()`` predicate gets the expression being called. ``Name.getId()`` gets the identifier (as a string) of the ``Name`` expression. Due to the dynamic nature of Python, this query will select any call of the form ``eval(...)`` regardless of whether it is a call to the built-in function ``eval`` or not. In a later tutorial we will see how to use the type-inference library to find calls to the built-in function ``eval`` regardless of name of the variable called. diff --git a/docs/codeql/codeql-language-guides/javadoc.rst b/docs/codeql/codeql-language-guides/javadoc.rst index 7e16cc6ce36..c1bce79a0a2 100644 --- a/docs/codeql/codeql-language-guides/javadoc.rst +++ b/docs/codeql/codeql-language-guides/javadoc.rst @@ -149,8 +149,6 @@ Now we can write a query for finding all callables ``c`` and ``@throws`` tags `` not mayThrow(c, exn) select tt, "Spurious @throws tag." -➤ `See this in the query console on LGTM.com `__. This finds several results in the LGTM.com demo projects. - Improvements ~~~~~~~~~~~~ @@ -216,7 +214,7 @@ The first case can be covered by changing ``getDocumentedException`` to use the (result.hasName(tt.getExceptionName()) and visibleIn(tt.getFile(), result)) } -➤ `See this in the query console on LGTM.com `__. This finds many fewer, more interesting results in the LGTM.com demo projects. +This query should find many fewer, more interesting results. Currently, ``visibleIn`` only considers single-type imports, but you could extend it with support for other kinds of imports. diff --git a/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst b/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst index 8b73b49153b..6db902ea4b8 100644 --- a/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst +++ b/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst @@ -80,7 +80,7 @@ We can use the ``Callable`` class to write a query that finds methods that are n where not exists(Callable caller | caller.polyCalls(callee)) select callee -➤ `See this in the query console on LGTM.com `__. This simple query typically returns a large number of results. +This simple query typically returns a large number of results. .. pull-quote:: @@ -99,7 +99,7 @@ Running this query on a typical Java project results in lots of hits in the Java callee.getCompilationUnit().fromSource() select callee, "Not called." -➤ `See this in the query console on LGTM.com `__. This change reduces the number of results returned for most projects. +This change reduces the number of results returned for most codebases. We might also notice several unused methods with the somewhat strange name ````: these are class initializers; while they are not explicitly called anywhere in the code, they are called implicitly whenever the surrounding class is loaded. Hence it makes sense to exclude them from our query. While we are at it, we can also exclude finalizers, which are similarly invoked implicitly: @@ -113,7 +113,7 @@ We might also notice several unused methods with the somewhat strange name ``") and not callee.hasName("finalize") select callee, "Not called." -➤ `See this in the query console on LGTM.com `__. This also reduces the number of results returned by most projects. +This also reduces the number of results returned by most codebases. We may also want to exclude public methods from our query, since they may be external API entry points: @@ -128,7 +128,7 @@ We may also want to exclude public methods from our query, since they may be ext not callee.isPublic() select callee, "Not called." -➤ `See this in the query console on LGTM.com `__. This should have a more noticeable effect on the number of results returned. +This should have a more noticeable effect on the number of results returned. A further special case is non-public default constructors: in the singleton pattern, for example, a class is provided with private empty default constructor to prevent it from being instantiated. Since the very purpose of such constructors is their not being called, they should not be flagged up: @@ -144,7 +144,7 @@ A further special case is non-public default constructors: in the singleton patt not callee.(Constructor).getNumberOfParameters() = 0 select callee, "Not called." -➤ `See this in the query console on LGTM.com `__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects. +This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects. Finally, on many Java projects there are methods that are invoked indirectly by reflection. So, while there are no calls invoking these methods, they are, in fact, used. It is in general very hard to identify such methods. A very common special case, however, is JUnit test methods, which are reflectively invoked by a test runner. The CodeQL library for Java has support for recognizing test classes of JUnit and other testing frameworks, which we can employ to filter out methods defined in such classes: @@ -161,7 +161,7 @@ Finally, on many Java projects there are methods that are invoked indirectly by not callee.getDeclaringType() instanceof TestClass select callee, "Not called." -➤ `See this in the query console on LGTM.com `__. This should give a further reduction in the number of results returned. +This should give a further reduction in the number of results returned. Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst index b0762a5c139..53c36c7f786 100644 --- a/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst +++ b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst @@ -44,7 +44,7 @@ We'll start by writing a query that finds less-than expressions (CodeQL class `` expr.getRightOperand().getType().hasName("long") select expr -➤ `See this in the query console on LGTM.com `__. This query usually finds results on most projects. +This query usually finds results on most codebases. Notice that we use the predicate ``getType`` (available on all subclasses of ``Expr``) to determine the type of the operands. Types, in turn, define the ``hasName`` predicate, which allows us to identify the primitive types ``int`` and ``long``. As it stands, this query finds *all* less-than expressions comparing ``int`` and ``long``, but in fact we are only interested in comparisons that are part of a loop condition. Also, we want to filter out comparisons where either operand is constant, since these are less likely to be real bugs. The revised query looks like this: @@ -59,7 +59,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E not expr.getAnOperand().isCompileTimeConstant() select expr -➤ `See this in the query console on LGTM.com `__. Notice that fewer results are found. +Notice that fewer results are found. The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself. @@ -113,16 +113,44 @@ Now we rewrite our query to make use of these new classes: .. code-block:: ql - import Java + import java - // Insert the class definitions from above + // Return the width (in bits) of a given integral type + int width(PrimitiveType pt) { + (pt.hasName("byte") and result=8) or + (pt.hasName("short") and result=16) or + (pt.hasName("char") and result=16) or + (pt.hasName("int") and result=32) or + (pt.hasName("long") and result=64) + } - from OverflowProneComparison expr - where exists(LoopStmt l | l.getCondition().getAChildExpr*() = expr) and - not expr.getAnOperand().isCompileTimeConstant() - select expr + // Find any comparison where the width of the type on the smaller end of + // the comparison is less than the width of the type on the greater end + abstract class OverflowProneComparison extends ComparisonExpr { + Expr getLesserOperand() { none() } + Expr getGreaterOperand() { none() } + } -➤ `See the full query in the query console on LGTM.com `__. + // Return `<=` and `<` comparisons + class LTOverflowProneComparison extends OverflowProneComparison { + LTOverflowProneComparison() { + (this instanceof LEExpr or this instanceof LTExpr) and + width(this.getLeftOperand().getType()) < width(this.getRightOperand().getType()) + } + } + + // Return `>=` and `>` comparisons + class GTOverflowProneComparison extends OverflowProneComparison { + GTOverflowProneComparison() { + (this instanceof GEExpr or this instanceof GTExpr) and + width(this.getRightOperand().getType()) < width(this.getLeftOperand().getType()) + } + } + + from OverflowProneComparison expr + where exists(LoopStmt l | l.getCondition().getAChildExpr*() = expr) and + not expr.getAnOperand().isCompileTimeConstant() + select expr Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst index d2a6cee326a..049dc95ad9b 100644 --- a/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst +++ b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst @@ -146,8 +146,6 @@ Finally we can simplify the query by using the transitive closure operator. In t and exists(c.getBlock()) select c, "Constructor does not initialize fields $@.", f, f.getName() -➤ `See this in the query console on LGTM.com `__ - Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/types-in-java.rst b/docs/codeql/codeql-language-guides/types-in-java.rst index 04cc716b961..3bb1c59fed7 100644 --- a/docs/codeql/codeql-language-guides/types-in-java.rst +++ b/docs/codeql/codeql-language-guides/types-in-java.rst @@ -34,7 +34,7 @@ To determine ancestor types (including immediate super types, and also *their* s where B.hasName("B") select B.getASupertype+() -➤ `See this in the query console on LGTM.com `__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``. +If we ran this query on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``. .. pull-quote:: @@ -80,7 +80,7 @@ This recipe is not too difficult to translate into a query: target.getElementType().(RefType).getASupertype+() = source.getElementType() select ce, "Potentially problematic array downcast." -➤ `See this in the query console on LGTM.com `__. Many projects return results for this query. +Many projects return results for this query. Note that by casting ``target.getElementType()`` to a ``RefType``, we eliminate all cases where the element type is a primitive type, that is, ``target`` is an array of primitive type: the problem we are looking for cannot arise in that case. Unlike in Java, a cast in QL never fails: if an expression cannot be cast to the desired type, it is simply excluded from the query results, which is exactly what we want. @@ -143,7 +143,7 @@ Using these new classes we can extend our query to exclude calls to ``toArray`` not ce.getExpr().(CollectionToArrayCall).getActualReturnType() = target select ce, "Potentially problematic array downcast." -➤ `See this in the query console on LGTM.com `__. Notice that fewer results are found by this improved query. +Notice that fewer results are found by this improved query. Example: Finding mismatched contains checks ------------------------------------------- @@ -269,8 +269,6 @@ Now we are ready to write a first version of our query: not haveCommonDescendant(collEltType, argType) select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType -➤ `See this in the query console on LGTM.com `__. - Improvements ~~~~~~~~~~~~ @@ -284,19 +282,50 @@ Adding these three improvements, our final query becomes: .. code-block:: ql - import java + import java - // Insert the class definitions from above + class JavaUtilCollection extends GenericInterface { + JavaUtilCollection() { + this.hasQualifiedName("java.util", "Collection") + } + } - from JavaUtilCollectionContainsCall juccc, Type collEltType, Type argType - where collEltType = juccc.getCollectionElementType() and argType = juccc.getArgumentType() and - not haveCommonDescendant(collEltType, argType) and - not collEltType instanceof TypeVariable and not argType instanceof TypeVariable and - not collEltType = argType.(PrimitiveType).getBoxedType() and - not argType.hasName("") - select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType + class JavaUtilCollectionContains extends Method { + JavaUtilCollectionContains() { + this.getDeclaringType() instanceof JavaUtilCollection and + this.hasStringSignature("contains(Object)") + } + } -➤ `See the full query in the query console on LGTM.com `__. + class JavaUtilCollectionContainsCall extends MethodAccess { + JavaUtilCollectionContainsCall() { + exists(JavaUtilCollectionContains jucc | + this.getMethod().getSourceDeclaration().overrides*(jucc) + ) + } + Type getArgumentType() { + result = this.getArgument(0).getType() + } + Type getCollectionElementType() { + exists(RefType D, ParameterizedInterface S | + D = this.getMethod().getDeclaringType() and + D.hasSupertype*(S) and S.getSourceDeclaration() instanceof JavaUtilCollection and + result = S.getTypeArgument(0) + ) + } + } + + predicate haveCommonDescendant(RefType tp1, RefType tp2) { + exists(RefType commondesc | commondesc.hasSupertype*(tp1) and commondesc.hasSupertype*(tp2)) + } + + from JavaUtilCollectionContainsCall juccc, Type collEltType, Type argType + where collEltType = juccc.getCollectionElementType() and argType = juccc.getArgumentType() and + not haveCommonDescendant(collEltType, argType) and + not collEltType instanceof TypeVariable and not argType instanceof TypeVariable and + not collEltType = argType.(PrimitiveType).getBoxedType() and + not argType.hasName("") + select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType Further reading --------------- diff --git a/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst index 24be065c912..adfcdaa8d60 100644 --- a/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst +++ b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst @@ -29,8 +29,6 @@ following snippet demonstrates. select API::moduleImport("re") -➤ `See this in the query console on LGTM.com `__. - This query selects the API graph node corresponding to the ``re`` module. This node represents the fact that the ``re`` module has been imported rather than a specific location in the program where the import happens. Therefore, there will be at most one result per project, and it will not have a useful location, so you'll have to click `Show 1 non-source result` in order to see it. To find where the ``re`` module is referenced in the program, you can use the ``getAUse`` method. The following query selects all references to the ``re`` module in the current database. @@ -42,8 +40,6 @@ To find where the ``re`` module is referenced in the program, you can use the `` select API::moduleImport("re").getAUse() -➤ `See this in the query console on LGTM.com `__. - Note that the ``getAUse`` method accounts for local flow, so that ``my_re_compile`` in the following snippet is correctly recognized as a reference to the ``re.compile`` function. @@ -77,8 +73,6 @@ the above ``re.compile`` example, you can now find references to ``re.compile``. select API::moduleImport("re").getMember("compile").getAUse() -➤ `See this in the query console on LGTM.com `__. - In addition to ``getMember``, you can use the ``getUnknownMember`` method to find references to API components where the name is not known statically. You can use the ``getAMember`` method to access all members, both known and unknown. @@ -97,15 +91,11 @@ where the return value of ``re.compile`` is used: select API::moduleImport("re").getMember("compile").getReturn().getAUse() -➤ `See this in the query console on LGTM.com `__. - Note that this includes all uses of the result of ``re.compile``, including those reachable via local flow. To get just the *calls* to ``re.compile``, you can use ``getAnImmediateUse`` instead of ``getAUse``. As this is a common occurrence, you can use ``getACall`` instead of ``getReturn`` followed by ``getAnImmediateUse``. -➤ `See this in the query console on LGTM.com `__. - Note that the API graph does not distinguish between class instantiations and function calls. As far as it's concerned, both are simply places where an API graph node is called. @@ -134,8 +124,6 @@ all subclasses of ``View``, you must explicitly include the subclasses of ``Meth select viewClass().getAUse() -➤ `See this in the query console on LGTM.com `__. - Note the use of the set literal ``["View", "MethodView"]`` to match both classes simultaneously. Built-in functions and classes diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index c2f93525341..597ce491463 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -338,10 +338,9 @@ step by step in the UI: where cfg.hasFlowPath(source, sink) select sink, source, sink, "Property access on JSON value originating $@.", source, "here" -`Here `_ is a run of this query on the `plexus-interop -`_ project on LGTM.com. Many of the 19 -results are false positives since we currently do not model many ways in which a value can be -checked for nullness. In particular, after a property reference ``x.p`` we implicitly know that +We ran this query on the https://github.com/finos/plexus-interop repository. Many of the +results were false positives since the query does not currently model many ways in which we can check +a value for nullness. In particular, after a property reference ``x.p`` we implicitly know that ``x`` cannot be null anymore, since otherwise the reference would have thrown an exception. Modeling this would allow us to get rid of most of the false positives, but is beyond the scope of this tutorial. @@ -391,10 +390,10 @@ Some of our standard security queries use flow labels. You can look at their imp to get a feeling for how to use flow labels in practice. In particular, both of the examples mentioned in the section on limitations of basic data flow above -are from standard security queries that use flow labels. The `Prototype pollution -`_ query uses two flow labels to distinguish completely +are from standard security queries that use flow labels. The `Prototype-polluting merge call +`_ query uses two flow labels to distinguish completely tainted objects from partially tainted objects. The `Uncontrolled data used in path expression -`_ query uses four flow labels to track whether a user-controlled +`_ query uses four flow labels to track whether a user-controlled string may be an absolute path and whether it may contain ``..`` components. Further reading diff --git a/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst b/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst index e1690397e63..6d14e9413af 100644 --- a/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst +++ b/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst @@ -228,15 +228,23 @@ Here's see an example of what this can handle now: Tracking in the whole model --------------------------- -We applied this pattern to ``firebaseDatabase()`` in the previous section, and it -can just as easily apply to the other predicates. -For reference, here's our simple Firebase model with type tracking on every predicate: +We applied this pattern to ``firebaseDatabase()`` in the previous section, and we can +apply the model just as easily to other predicates. +This example query uses the model to find `set` calls. +It's been modified slightly to handle a bit more of the API, which is beyond the scope of this tutorial. .. code-block:: ql + import javascript + import DataFlow + SourceNode firebase(TypeTracker t) { t.start() and - result = globalVarRef("firebase") + ( + result = globalVarRef("firebase") + or + result = moduleImport("firebase/app") + ) or exists(TypeTracker t2 | result = firebase(t2).track(t2, t) @@ -277,8 +285,7 @@ For reference, here's our simple Firebase model with type tracking on every pred result = firebaseRef().getAMethodCall("set") } -`Here `__ is a run of an example query using the model to find `set` calls on one of the Firebase sample projects. -It's been modified slightly to handle a bit more of the API, which is beyond the scope of this tutorial. + select firebaseSetterCall() Tracking associated data ------------------------ @@ -392,7 +399,98 @@ Based on that we can track the ``snapshot`` value and find the ``val()`` call it With this addition, ``firebaseDatabaseRead("forecast")`` finds the call to ``snapshot.val()`` that contains the value of the forecast. -`Here `__ is a run of an example query using the model to find `val` calls. +.. code-block:: ql + + import javascript + import DataFlow + + SourceNode firebase(TypeTracker t) { + t.start() and + ( + result = globalVarRef("firebase") + or + result = moduleImport("firebase/app") + ) + or + exists(TypeTracker t2 | + result = firebase(t2).track(t2, t) + ) + } + + SourceNode firebase() { + result = firebase(TypeTracker::end()) + } + + SourceNode firebaseDatabase(TypeTracker t) { + t.start() and + result = firebase().getAMethodCall("database") + or + exists(TypeTracker t2 | + result = firebaseDatabase(t2).track(t2, t) + ) + } + + SourceNode firebaseDatabase() { + result = firebaseDatabase(TypeTracker::end()) + } + + SourceNode firebaseRef(Node name, TypeTracker t) { + t.start() and + exists(CallNode call | + call = firebaseDatabase().getAMethodCall("ref") and + name = call.getArgument(0) and + result = call + ) + or + exists(TypeTracker t2 | + result = firebaseRef(name, t2).track(t2, t) + ) + } + + SourceNode firebaseRef(Node name) { + result = firebaseRef(name, TypeTracker::end()) + } + + MethodCallNode firebaseSetterCall(Node name) { + result = firebaseRef(name).getAMethodCall("set") + } + + SourceNode firebaseSnapshotCallback(Node refName, TypeBackTracker t) { + t.start() and + ( + result = firebaseRef(refName).getAMethodCall("once").getArgument(1).getALocalSource() + or + result = firebaseRef(refName).getAMethodCall("once").getAMethodCall("then").getArgument(0).getALocalSource() + ) + or + exists(TypeBackTracker t2 | + result = firebaseSnapshotCallback(refName, t2).backtrack(t2, t) + ) + } + + FunctionNode firebaseSnapshotCallback(Node refName) { + result = firebaseSnapshotCallback(refName, TypeBackTracker::end()) + } + + SourceNode firebaseSnapshot(Node refName, TypeTracker t) { + t.start() and + result = firebaseSnapshotCallback(refName).getParameter(0) + or + exists(TypeTracker t2 | + result = firebaseSnapshot(refName, t2).track(t2, t) + ) + } + + SourceNode firebaseSnapshot(Node refName) { + result = firebaseSnapshot(refName, TypeTracker::end()) + } + + MethodCallNode firebaseDatabaseRead(Node refName) { + result = firebaseSnapshot(refName).getAMethodCall("val") + } + + from Node name + select name, firebaseDatabaseRead(name) Summary ------- diff --git a/docs/codeql/codeql-language-guides/working-with-source-locations.rst b/docs/codeql/codeql-language-guides/working-with-source-locations.rst index 9b55b95df52..90cc5f17849 100644 --- a/docs/codeql/codeql-language-guides/working-with-source-locations.rst +++ b/docs/codeql/codeql-language-guides/working-with-source-locations.rst @@ -112,7 +112,7 @@ Here's a first version of our query: wsinner > wsouter select outer, "Whitespace around nested operators contradicts precedence." -➤ `See this in the query console on LGTM.com `__. This query is likely to find results on most projects. +This query is likely to find results on most codebases. The first conjunct of the ``where`` clause restricts ``inner`` to be an operand of ``outer``, the second conjunct binds ``wsinner`` and ``wsouter``, while the last conjunct selects the suspicious cases. @@ -143,7 +143,7 @@ Note that our predicate ``operatorWS`` computes the **total** amount of white sp wsinner > wsouter select outer, "Whitespace around nested operators contradicts precedence." -➤ `See this in the query console on LGTM.com `__. Any results will be refined by our changes to the query. +Any results will be refined by our changes to the query. Another source of false positives are associative operators: in an expression of the form ``x + y+z``, the first plus is syntactically nested inside the second, since + in Java associates to the left; hence the expression is flagged as suspicious. But since + is associative to begin with, it does not matter which way around the operators are nested, so this is a false positive. To exclude these cases, let us define a new class identifying binary expressions with an associative operator: @@ -175,8 +175,6 @@ Now we can extend our query to discard results where the outer and the inner exp wsinner > wsouter select outer, "Whitespace around nested operators contradicts precedence." -➤ `See this in the query console on LGTM.com `__. - Notice that we again use ``getOp``, this time to determine whether two binary expressions have the same operator. Running our improved query now finds the Java standard library bug described in the Overview. It also flags up the following suspicious code in `Hadoop HBase `__: .. code-block:: java diff --git a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst index be66125846a..7cb78873ceb 100644 --- a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst +++ b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst @@ -16,7 +16,7 @@ CodeQL library packs (`source `__) support the following languages and compilers. -.. include:: ../support/reusables/versions-compilers.rst +.. include:: ../reusables/supported-versions-compilers.rst Frameworks and libraries ######################## @@ -31,4 +31,4 @@ The current versions of the CodeQL library and query packs (`source ` - :doc:`CodeQL query help for C# ` - :doc:`CodeQL query help for Go ` -- :doc:`CodeQL query help for Java ` +- :doc:`CodeQL query help for Java and Kotlin ` - :doc:`CodeQL query help for JavaScript ` - :doc:`CodeQL query help for Python ` - :doc:`CodeQL query help for Ruby ` +.. include:: ../reusables/kotlin-beta-note.rst + .. pull-quote:: Information Each query help article includes: diff --git a/docs/codeql/reusables/extractors.rst b/docs/codeql/reusables/extractors.rst index a3a4952811d..606c57d0208 100644 --- a/docs/codeql/reusables/extractors.rst +++ b/docs/codeql/reusables/extractors.rst @@ -10,7 +10,7 @@ - ``csharp`` * - Go - ``go`` - * - Java + * - Java/Kotlin - ``java`` * - JavaScript/TypeScript - ``javascript`` diff --git a/docs/codeql/reusables/kotlin-beta-note.rst b/docs/codeql/reusables/kotlin-beta-note.rst new file mode 100644 index 00000000000..d05d137a13e --- /dev/null +++ b/docs/codeql/reusables/kotlin-beta-note.rst @@ -0,0 +1,4 @@ + .. pull-quote:: Note + + CodeQL analysis for Kotlin is currently in beta. During the beta, analysis of Kotlin code, + and the accompanying documentation, will not be as comprehensive as for other languages. \ No newline at end of file diff --git a/docs/codeql/reusables/kotlin-java-differences.rst b/docs/codeql/reusables/kotlin-java-differences.rst new file mode 100644 index 00000000000..40e18b60484 --- /dev/null +++ b/docs/codeql/reusables/kotlin-java-differences.rst @@ -0,0 +1,20 @@ +Writing CodeQL queries for Kotlin versus Java analysis +------------------------------------------------------ + +Generally you use the same classes to write queries for Kotlin and for Java. You use the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as ``MethodAccess`` or ``Class`` for both languages. When you want to access Kotlin-specific elements (such as a ``WhenExpr``) you’ll need to use Kotlin-specific CodeQL classes. + +There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing queries for Java, as CodeQL works with the JVM bytecode representation of the Kotlin source code. + +Be careful when you model code elements that don’t exist in Java, such as ``NotNullExpr (expr!!)``, because they could interact in unexpected ways with common predicates. For example, ``MethodAccess.getQualifier()`` returns a ``NotNullExpr`` instead of a ``VarAccess`` in the following Kotlin code: + +.. code-block:: kotlin + + someVar!!.someMethodCall() + +In that specific case, you can use the predicate ``Expr.getUnderlyingExpr()``. This goes directly to the underlying ``VarAccess`` to produce a more similar behavior to that in Java. + +Nullable elements (``?``) can also produce unexpected behavior. To avoid a ``NullPointerException``, Kotlin may inline calls like ``expr.toString()`` to ``String.valueOf(expr)`` when ``expr`` is nullable. Make sure that you write CodeQL around the extracted code, which may not exactly match the code as written in the codebase. + +Another example is that if-else expressions in Kotlin are translated into ``WhenExprs`` in CodeQL, instead of the more typical ``IfStmt`` seen in Java. + +In general, you can debug these issues with the AST (you can use the ``CodeQL: View AST`` command from Visual Studio Code’s CodeQL extension, or run the ``PrintAst.ql`` query) and see exactly what CodeQL is extracting from your code. \ No newline at end of file diff --git a/docs/codeql/reusables/setup-to-run-tutorials.rst b/docs/codeql/reusables/setup-to-run-tutorials.rst new file mode 100644 index 00000000000..de761968d8a --- /dev/null +++ b/docs/codeql/reusables/setup-to-run-tutorials.rst @@ -0,0 +1 @@ +For information about installing the CodeQL extension for Visual Studio code, see ":ref:`Setting up CodeQL in Visual Studio Code `." diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/reusables/supported-frameworks.rst similarity index 99% rename from docs/codeql/support/reusables/frameworks.rst rename to docs/codeql/reusables/supported-frameworks.rst index b83b26f486a..191b40b4896 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/reusables/supported-frameworks.rst @@ -93,9 +93,11 @@ and the CodeQL library pack ``codeql/go-all`` (`changelog `_, Serialization `zap `_, Logging library -Java built-in support +Java and Kotlin built-in support ================================== +.. include:: ../reusables/kotlin-beta-note.rst + Provided by the current versions of the CodeQL query pack ``codeql/java-queries`` (`changelog `__, `source `__) and the CodeQL library pack ``codeql/java-all`` (`changelog `__, `source `__). diff --git a/docs/codeql/support/reusables/platforms.rst b/docs/codeql/reusables/supported-platforms.rst similarity index 100% rename from docs/codeql/support/reusables/platforms.rst rename to docs/codeql/reusables/supported-platforms.rst diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst similarity index 94% rename from docs/codeql/support/reusables/versions-compilers.rst rename to docs/codeql/reusables/supported-versions-compilers.rst index d84757c81d7..85a650ed17a 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -24,7 +24,7 @@ JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [7]_" Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10",Not applicable,``.py`` Ruby [9]_,"up to 3.1",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``" - TypeScript [10]_,"2.6-4.8",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" + TypeScript [10]_,"2.6-4.9",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" .. container:: footnote-group @@ -37,4 +37,4 @@ .. [7] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. .. [8] The extractor requires Python 3 to run. To analyze Python 2.7 you should install both versions of Python. .. [9] Requires glibc 2.17. - .. [10] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. + .. [10] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default. diff --git a/docs/codeql/reusables/vs-code-basic-instructions/find-database.rst b/docs/codeql/reusables/vs-code-basic-instructions/find-database.rst new file mode 100644 index 00000000000..a0129d96677 --- /dev/null +++ b/docs/codeql/reusables/vs-code-basic-instructions/find-database.rst @@ -0,0 +1,23 @@ +Finding a CodeQL database to experiment with +-------------------------------------------- + +Before you start writing queries for |language-text| code, you need a CodeQL database to run them against. The simplest way to do this is to download a database for a repository that uses |language-text| directly from GitHub.com. + +#. In Visual Studio Code, click the **QL** icon |codeql-ext-icon| in the left sidebar to display the CodeQL extension. + +#. Click **From GitHub** or the GitHub logo |github-db| at the top of the CodeQL extension to open an entry field. + +#. Copy the URL for the repository into the field and press the keyboard **Enter** key. For example, |example-url|. + +#. Optionally, if the repository has more than one CodeQL database available, select |language-code| to download the database created from the |language-text| code. + +Information about the download progress for the database is shown in the bottom right corner of Visual Studio Code. When the download is complete, the database is shown with a check mark in the **Databases** section of the CodeQL extension (see screenshot below). + +.. |codeql-ext-icon| image:: ../images/codeql-for-visual-studio-code/codeql-extension-icon.png + :width: 20 + :alt: Icon for the CodeQL extension. + +.. |github-db| image:: ../images/codeql-for-visual-studio-code/add-codeql-db-github.png + :width: 20 + :alt: Icon for the CodeQL extension option to download a CodeQL database from GitHub. + diff --git a/docs/codeql/reusables/vs-code-basic-instructions/note-store-quick-query.rst b/docs/codeql/reusables/vs-code-basic-instructions/note-store-quick-query.rst new file mode 100644 index 00000000000..3638b37d35e --- /dev/null +++ b/docs/codeql/reusables/vs-code-basic-instructions/note-store-quick-query.rst @@ -0,0 +1,5 @@ +.. pull-quote:: + + Note + + If you want to move your experimental query somewhere more permanent, you need to move the whole ``Quick Queries`` directory. The directory is a CodeQL pack with a ``qlpack.yml`` file that defines the content as queries for |language-text| CodeQL databases. For more information about CodeQL packs, see ":ref:`Working with CodeQL packs in Visual Studio Code `." \ No newline at end of file diff --git a/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-1.rst b/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-1.rst new file mode 100644 index 00000000000..765eb115cd1 --- /dev/null +++ b/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-1.rst @@ -0,0 +1,7 @@ +The CodeQL extension for Visual Studio Code adds several **CodeQL:** commands to the command palette including **Quick Query**, which you can use to run a query without any set up. + +#. From the command palette in Visual Studio Code, select **CodeQL: Quick Query**. + +#. After a moment, a new tab *quick-query.ql* is opened, ready for you to write a query for your currently selected CodeQL database (here a |language-code| database). If you are prompted to reload your workspace as a multi-folder workspace to allow Quick queries, accept or create a new workspace using the starter workflow. + + |image-quick-query| \ No newline at end of file diff --git a/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-2.rst b/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-2.rst new file mode 100644 index 00000000000..5937edead68 --- /dev/null +++ b/docs/codeql/reusables/vs-code-basic-instructions/run-quick-query-2.rst @@ -0,0 +1,7 @@ +4. Save the query in its default location (a temporary "Quick Queries" directory under the workspace for ``GitHub.vscode-codeql/quick-queries``). + +#. Right-click in the query tab and select **CodeQL: Run Query**. (Alternatively, run the command from the Command Palette.) + + The query will take a few moments to return results. When the query completes, the results are displayed in a CodeQL Query Results view, next to the main editor view. + + The query results are listed in two columns, corresponding to the expressions in the ``select`` clause of the query. |result-col-1| The second column is the alert message. \ No newline at end of file diff --git a/docs/codeql/reusables/vs-code-basic-instructions/setup-to-run-queries.rst b/docs/codeql/reusables/vs-code-basic-instructions/setup-to-run-queries.rst new file mode 100644 index 00000000000..4e6ecf8daf2 --- /dev/null +++ b/docs/codeql/reusables/vs-code-basic-instructions/setup-to-run-queries.rst @@ -0,0 +1 @@ +For information about installing the CodeQL extension for Visual Studio code, see ":ref:`Setting up CodeQL in Visual Studio Code `." \ No newline at end of file diff --git a/docs/codeql/support/conf.py b/docs/codeql/support/conf.py deleted file mode 100644 index c8acb659695..00000000000 --- a/docs/codeql/support/conf.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# -# CodeQL analysis support for LGTM Enterprise docs build configuration file. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# For details of all possible config values, -# see https://www.sphinx-doc.org/en/master/usage/configuration.html - -############################################################################## -# -# Modified 22032021. - -# The configuration values below are specific to the supported languages and frameworks project -# To amend html_theme_options, update version/release number, or add more sphinx extensions, -# refer to code/documentation/ql-documentation/global-sphinx-files/global-conf.py - -############################################################################## - -# -- Project-specific configuration ----------------------------------- - -# Set QL as the default language for highlighting code. Set to none to disable -# syntax highlighting. If omitted or left blank, it defaults to Python 3. -highlight_language = 'none' - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# The master toctree document. -master_doc = 'index' - -# Project-specific information. -project = u'Supported languages and frameworks for LGTM Enterprise' - -# The version info for this project, if different from version and release in main conf.py file. -# The short X.Y version. - -# LGTM Enterprise release -release = u'1.30' - -# CodeQL CLI version used by LGTM Enterprise release -version = u'2.7.6' - -# -- Project-specifc options for HTML output ---------------------------------------------- - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -html_title = 'Supported languages and frameworks' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Supported languages and frameworks' - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['../_templates'] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['../_static'] - -html_theme_options = {'font_size': '16px', - 'body_text': '#333', - 'link': '#2F1695', - 'link_hover': '#2F1695', - 'show_powered_by': False, - 'nosidebar':True, - 'head_font_family': '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"', - } - -html_favicon = '../images/site/favicon.ico' - -# -- Currently unused, but potentially useful, configs-------------------------------------- - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['read-me-project.rst', 'reusables/*'] diff --git a/docs/codeql/support/framework-support.rst b/docs/codeql/support/framework-support.rst deleted file mode 100644 index d12b1a96c8f..00000000000 --- a/docs/codeql/support/framework-support.rst +++ /dev/null @@ -1,19 +0,0 @@ -Frameworks and libraries -######################## - -LGTM Enterprise |release| includes CodeQL CLI |version|. The CodeQL libraries and queries used by this version of LGTM Enterprise have been explicitly checked against the libraries and frameworks listed below. - -.. pull-quote:: - - Note - - For details of framework and library support in the most recent release of the CodeQL CLI, see `Supported languages and frameworks `__ in the CodeQL CLI documentation. - -.. pull-quote:: - - Tip - - If you're interested in other libraries or frameworks, you can extend the analysis to cover them. - For example, by extending the data flow libraries to include data sources and sinks for additional libraries or frameworks. - -.. include:: reusables/frameworks.rst diff --git a/docs/codeql/support/index.rst b/docs/codeql/support/index.rst deleted file mode 100644 index 89812242fce..00000000000 --- a/docs/codeql/support/index.rst +++ /dev/null @@ -1,19 +0,0 @@ -Supported languages and frameworks -################################## - -These pages describe the languages and frameworks supported in the latest enterprise release of CodeQL and LGTM. (CodeQL was previously known as QL.) -Users of `LGTM.com `_ may find that additional features are supported because it's updated more frequently. - -For details see: - -.. toctree:: - - language-support.rst - framework-support.rst - -For details of the CodeQL libraries, see `CodeQL standard libraries `_. - -.. toctree:: - :hidden: - - ql-training \ No newline at end of file diff --git a/docs/codeql/support/language-support.rst b/docs/codeql/support/language-support.rst deleted file mode 100644 index 49b90693a7c..00000000000 --- a/docs/codeql/support/language-support.rst +++ /dev/null @@ -1,16 +0,0 @@ -Languages and compilers -####################### - -LGTM Enterprise |release| includes CodeQL CLI |version|. LGTM Enterprise supports analysis of the following languages compiled by the following compilers. - -.. pull-quote:: - - Note - - For details of language and compiler support in the most recent release of the CodeQL CLI, see `Supported languages and frameworks `__ in the CodeQL CLI documentation. - -Note that where there are several versions or dialects of a language, the supported variants are listed. -If your code requires a particular version of a compiler, check that this version is included below. -If you have any questions about language and compiler support, you can find help on the `GitHub Security Lab discussions board `__. - -.. include:: reusables/versions-compilers.rst diff --git a/docs/codeql/support/ql-training.rst b/docs/codeql/support/ql-training.rst deleted file mode 100644 index 6eb8019e5c9..00000000000 --- a/docs/codeql/support/ql-training.rst +++ /dev/null @@ -1,63 +0,0 @@ -CodeQL training and variant analysis examples -============================================= - -CodeQL and variant analysis ---------------------------- - -Variant analysis is the process of using a known vulnerability as a seed to find similar problems in your code. Security engineers typically perform variant analysis to identify possible vulnerabilities and to ensure that these threats are properly fixed across multiple code bases. - -CodeQL is the code analysis engine that underpins LGTM, the community driven security analysis platform. Together, CodeQL and LGTM provide continuous monitoring and scalable variant analysis for your projects, even if you don’t have your own team of dedicated security engineers. You can read more about using CodeQL and LGTM in variant analysis on the `Security Lab research page `__. - -CodeQL is easy to learn, and exploring code using CodeQL is the most efficient way to perform variant analysis. - -Learning CodeQL for variant analysis ------------------------------------- - -Start learning how to use CodeQL in variant analysis for a specific language by looking at the topics below. Each topic links to a short presentation on CodeQL, its libraries, or an example variant discovered using CodeQL. - -.. |arrow-l| unicode:: U+2190 - -.. |arrow-r| unicode:: U+2192 - -.. |info| unicode:: U+24D8 - -When you have selected a presentation, use |arrow-r| and |arrow-l| to navigate between slides. -Press **p** to view the additional notes on slides that have an information icon |info| in the top right corner, and press **f** to enter full-screen mode. - -The presentations contain a number of query examples. -We recommend that you download `CodeQL for Visual Studio Code `__ and add the example database for each presentation so that you can find the bugs mentioned in the slides. - - -.. pull-quote:: - - Information - - The presentations listed below are used in CodeQL and variant analysis training sessions run by GitHub engineers. - Therefore, be aware that the slides are designed to be presented by an instructor. - If you are using the slides without an instructor, please use the additional notes to help guide you through the examples. - -CodeQL and variant analysis for C/C++ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- `Introduction to variant analysis: CodeQL for C/C++ `__–an introduction to variant analysis and CodeQL for C/C++ programmers. -- `Example: Bad overflow guard `__–an example of iterative query development to find bad overflow guards in a C++ project. -- `Program representation: CodeQL for C/C++ `__–information on how CodeQL analysis represents C/C++ programs. -- `Introduction to local data flow `__–an introduction to analyzing local data flow in C/C++ using CodeQL, including an example demonstrating how to develop a query to find a real CVE. -- `Exercise: snprintf overflow `__–an example demonstrating how to develop a data flow query. -- `Introduction to global data flow `__–an introduction to analyzing global data flow in C/C++ using CodeQL. -- `Analyzing control flow: CodeQL for C/C++ `__–an introduction to analyzing control flow in C/C++ using CodeQL. - -CodeQL and variant analysis for Java -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- `Introduction to variant analysis: CodeQL for Java `__–an introduction to variant analysis and CodeQL for Java programmers. -- `Example: Query injection `__–an example of iterative query development to find unsanitized SPARQL injections in a Java project. -- `Program representation: CodeQL for Java `__–information on how CodeQL analysis represents Java programs. -- `Introduction to local data flow `__–an introduction to analyzing local data flow in Java using CodeQL, including an example demonstrating how to develop a query to find a real CVE. -- `Exercise: Apache Struts `__–an example demonstrating how to develop a data flow query. -- `Introduction to global data flow `__–an introduction to analyzing global data flow in Java using CodeQL. - -Further reading -~~~~~~~~~~~~~~~ - -- `GitHub Security Lab `__ diff --git a/docs/codeql/support/read-me-project.rst b/docs/codeql/support/read-me-project.rst deleted file mode 100644 index 81182043793..00000000000 --- a/docs/codeql/support/read-me-project.rst +++ /dev/null @@ -1,15 +0,0 @@ -Publishing this project for a new version -######################################### - -To update this project for a new version: - -1. Check with the language teams that all information in the ``ql/change-notes/support/`` directory is ready. - -2. Open the ``global-conf.py`` file in the ``global-sphinx-files`` directory and change the following variables -to the correct value(s) if necessary: - - * ``version =`` - * ``release = `` - * If it's the first release of the year, ``copyright =`` - -3. Commit your changes. The output of the ``doc/sphinx`` PR check should be correct for the new version and ready to publish. \ No newline at end of file diff --git a/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst b/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst index 60840e8bc9f..4cd9bb2ede8 100644 --- a/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst +++ b/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst @@ -105,7 +105,7 @@ Now try applying ``isAllowedIn(string region)`` to a person ``p``. If ``p`` is n You know that the fire starters live in the south *and* that they must have been able to travel to the north. Write a query to find the possible suspects. You could also extend the ``select`` clause to list the age of the suspects. That way you can clearly see that all the children have been excluded from the list. -➤ `See the answer in the query console on LGTM.com `__ +➤ `Check your answer <#exercise-1>`__ You can now continue to gather more clues and find out which of your suspects started the fire... @@ -142,7 +142,7 @@ The predicate ``isBald`` is defined to take a ``Person``, so it can also take a You can now write a query to select the bald southerners who are allowed into the north. -➤ `See the answer in the query console on LGTM.com `__ +➤ `Check your answer <#exercise-2>`__ You have found the two fire starters! They are arrested and the villagers are once again impressed with your work. @@ -150,3 +150,65 @@ Further reading --------------- .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +-------------- + +Answers +------- + +In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*. + +Exercise 1 +~~~~~~~~~~ + +.. code-block:: ql + + import tutorial + + predicate isSouthern(Person p) { p.getLocation() = "south" } + + class Southerner extends Person { + /* the characteristic predicate */ + Southerner() { isSouthern(this) } + } + + class Child extends Person { + /* the characteristic predicate */ + Child() { this.getAge() < 10 } + + /* a member predicate */ + override predicate isAllowedIn(string region) { region = this.getLocation() } + } + + from Southerner s + where s.isAllowedIn("north") + select s, s.getAge() + +Exercise 2 +~~~~~~~~~~ + +.. code-block:: ql + + import tutorial + + predicate isSouthern(Person p) { p.getLocation() = "south" } + + class Southerner extends Person { + /* the characteristic predicate */ + Southerner() { isSouthern(this) } + } + + class Child extends Person { + /* the characteristic predicate */ + Child() { this.getAge() < 10 } + + /* a member predicate */ + override predicate isAllowedIn(string region) { region = this.getLocation() } + } + + predicate isBald(Person p) { not exists(string c | p.getHairColor() = c) } + + from Southerner s + where s.isAllowedIn("north") and isBald(s) + select s + diff --git a/docs/codeql/writing-codeql-queries/cross-the-river.rst b/docs/codeql/writing-codeql-queries/cross-the-river.rst index c94806f90e9..dbee51b35dc 100644 --- a/docs/codeql/writing-codeql-queries/cross-the-river.rst +++ b/docs/codeql/writing-codeql-queries/cross-the-river.rst @@ -260,21 +260,34 @@ Alternative solutions Here are some more example queries that solve the river crossing puzzle: - #. This query uses a modified ``path`` variable to describe the resulting path in - more detail. +.. container:: toggle - ➤ `See solution in the query console on LGTM.com `__ + .. container:: name - #. This query models the man and the cargo items in a different way, using an - :ref:`abstract ` - class and predicate. It also displays the resulting path in a more visual way. + *Show/hide example query - modified path* - ➤ `See solution in the query console on LGTM.com `__ + .. literalinclude:: river-answer-1-path.ql + :language: ql - #. This query introduces :ref:`algebraic datatypes ` - to model the situation, instead of defining everything as a subclass of ``string``. - ➤ `See solution in the query console on LGTM.com `__ +.. container:: toggle + + .. container:: name + + *Show/hide example query - abstract class* + + .. literalinclude:: river-answer-2-abstract-class.ql + :language: ql + + +.. container:: toggle + + .. container:: name + + *Show/hide example query - datatypes* + + .. literalinclude:: river-answer-3-datatypes.ql + :language: ql Further reading --------------- diff --git a/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst b/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst index a9a8ace0775..b0512fde26b 100644 --- a/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst +++ b/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst @@ -129,7 +129,7 @@ Here is one way to define ``relativeOf()``: Don't forget to use the predicate ``isDeceased()`` to find relatives that are still alive. -➤ `See the answer in the query console on LGTM.com `__ +➤ `Check your answer <#exercise-1>`__ Select the true heir -------------------- @@ -142,7 +142,7 @@ To decide who should inherit the king's fortune, the villagers carefully read th As your final challenge, define a predicate ``hasCriminalRecord`` so that ``hasCriminalRecord(p)`` holds if ``p`` is any of the criminals you unmasked earlier (in the ":doc:`Find the thief `" and ":doc:`Catch the fire starter `" tutorials). -➤ `See the answer in the query console on LGTM.com `__ +➤ `Check your answer <#exercise-2>`__ Experimental explorations ------------------------- @@ -164,3 +164,47 @@ Further reading --------------- .. include:: ../reusables/codeql-ref-tools-further-reading.rst + +-------------- + +Answers +------- + +In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*. + +Exercise 1 +~~~~~~~~~~ + +.. code-block:: ql + + import tutorial + + Person relativeOf(Person p) { parentOf*(result) = parentOf*(p) } + + from Person p + where + not p.isDeceased() and + p = relativeOf("King Basil") + select p + +Exercise 2 +~~~~~~~~~~ + +.. code-block:: ql + + import tutorial + + Person relativeOf(Person p) { parentOf*(result) = parentOf*(p) } + + predicate hasCriminalRecord(Person p) { + p = "Hester" or + p = "Hugh" or + p = "Charlie" + } + + from Person p + where + not p.isDeceased() and + p = relativeOf("King Basil") and + not hasCriminalRecord(p) + select p diff --git a/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst b/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst index 9b17b257ac9..1cf0a31289b 100644 --- a/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst +++ b/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst @@ -9,8 +9,8 @@ About query results ------------------- The information contained in the results of a query is controlled by the ``select`` statement. Part of the process of developing a useful query is to make the results clear and easy for other users to understand. -When you write your own queries in the query console or in the CodeQL :ref:`extension for VS Code ` there are no constraints on what can be selected. -However, if you want to use a query to create alerts in LGTM or generate valid analysis results using the :ref:`CodeQL CLI `, you'll need to make the ``select`` statement report results in the required format. +When you write your own queries in the CodeQL :ref:`extension for VS Code ` there are no constraints on what can be selected. +However, if you want to use a query to create alerts for code scanning or generate valid analysis results using the :ref:`CodeQL CLI `, you'll need to make the ``select`` statement report results in the required format. You must also ensure that the query has the appropriate metadata properties defined. This topic explains how to write your select statement to generate helpful analysis results. @@ -23,7 +23,7 @@ In their most basic form, the ``select`` statement must select two 'columns': - **Element**—a code element that's identified by the query. This defines the location of the alert. - **String**—a message to display for this code element, describing why the alert was generated. -If you look at some of the LGTM queries, you'll see that they can select extra element/string pairs, which are combined with ``$@`` placeholder markers in the message to form links. For example, `Dereferenced variable may be null `__ (Java), or `Duplicate switch case `__ (JavaScript). +If you look at some of the existing queries, you'll see that they can select extra element/string pairs, which are combined with ``$@`` placeholder markers in the message to form links. For example, `Dereferenced variable may be null `__ (Java), or `Duplicate switch case `__ (JavaScript). .. pull-quote:: @@ -34,78 +34,70 @@ If you look at some of the LGTM queries, you'll see that they can select extra e Developing a select statement ----------------------------- -Here's a simple query that uses the standard CodeQL ``CodeDuplication.qll`` library to identify similar files. +Here's a simple query to find Java classes that extend other classes. Basic select statement ~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: ql - import java - import external.CodeDuplication - - from File f, File other, int percent - where similarFiles(f, other, percent) - select f, "This file is similar to another file." + /** + * @kind problem + */ + + import java + + from Class c, Class superclass + where superclass = c.getASupertype() + select c, "This class extends another class." This basic select statement has two columns: -#. Element to display the alert on: ``f`` corresponds to ``File``. -#. String message to display: ``"This file is similar to another file."`` +#. An element with a location to display the alert on: ``c`` corresponds to ``Class``. +#. String message to display: ``"This class extends another class."`` .. image:: ../images/ql-select-statement-basic.png :alt: Results of basic select statement :class: border -Including the name of the similar file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Including the name of the superclass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The alert message defined by the basic select statement is constant and doesn't give users much information. Since the query identifies the similar file (``other``), it's easy to extend the ``select`` statement to report the name of the similar file. For example: +The alert message defined by the basic select statement is constant and doesn't give users much information. Since the query identifies the superclass, it's easy to include its name in the string message. For example: .. code-block:: ql - select f, "This file is similar to " + other.getBaseName() + select c, "This class extends the class " + superclass.getName() -#. Element: ``f`` as before. -#. String message: ``"This file is similar to "``—the string text is combined with the file name for the ``other``, similar file, returned by ``getBaseName()``. +#. Element: ``c`` as before. +#. String message: ``"This class extends the class "``—the string text is combined with the class name for the ``superclass``, returned by ``getName()``. -.. image:: ../images/ql-select-statement-filename.png +.. image:: ../images/ql-select-statement-class-name.png :alt: Results of extended select statement :class: border -While this is more informative than the original select statement, the user still needs to find the other file manually. +While this is more informative than the original select statement, the user still needs to find the superclass manually. -Adding a link to the similar file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding a link to the superclass +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can use placeholders in the text of alert messages to insert additional information, such as links to the similar file. Placeholders are defined using ``$@``, and filled using the information in the next two columns of the select statement. For example, this select statement returns four columns: +You can use placeholders in the text of alert messages to insert additional information, such as links to the superclass. Placeholders are defined using ``$@``, and filled using the information in the next two columns of the select statement. For example, this select statement returns four columns: .. code-block:: ql - select f, "This file is similar to $@.", other, other.getBaseName() + select c, "This class extends the class $@.", superclass, superclass.getName() -#. Element: ``f`` as before. -#. String message: ``"This file is similar to $@."``—the string text now includes a placeholder, which will display the combined content of the next two columns. -#. Element for placeholder: ``other`` corresponds to the similar file. -#. String text for placeholder: the short file name returned by ``other.getBaseName()``. +#. Element: ``c`` as before. +#. String message: ``"This class extends the class $@."``—the string text now includes a placeholder, which will display the combined content of the next two columns. +#. Element for placeholder: the ``superclass``. +#. String text for placeholder: the class name returned by ``superclass.getBaseName()``. -When the alert message is displayed, the ``$@`` placeholder is replaced by a link created from the contents of the third and fourth columns defined by the ``select`` statement. +When the alert message is displayed, the ``$@`` placeholder is replaced by a link created from the contents of the third and fourth columns defined by the ``select`` statement. In this example, the link target will be the location of the superclass's definition, and the link text will be its name. Note that some superclasses, such as ``Object``, will not be in the database, since they are built in to the Java language. Clicking those links will have no effect. If you use the ``$@`` placeholder marker multiple times in the description text, then the ``N``\ th use is replaced by a link formed from columns ``2N+2`` and ``2N+3``. If there are more pairs of additional columns than there are placeholder markers, then the trailing columns are ignored. Conversely, if there are fewer pairs of additional columns than there are placeholder markers, then the trailing markers are treated as normal text rather than placeholder markers. -Adding details of the extent of similarity -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You could go further and change the ``select`` statement to report on the similarity of content in the two files, since this information is already available in the query. For example: - -.. code-block:: ql - - select f, percent + "% of the lines in " + f.getBaseName() + " are similar to lines in $@.", other, other.getBaseName() - -The new elements added here don't need to be clickable, so we added them directly to the description string. - -.. image:: ../images/ql-select-statement-similarity.png - :alt: Results showing the extent of similarity +.. image:: ../images/ql-select-statement-link.png + :alt: Results including links :class: border Further reading diff --git a/docs/codeql/writing-codeql-queries/find-the-thief.rst b/docs/codeql/writing-codeql-queries/find-the-thief.rst index ff9ee49f5dc..fd992741dbe 100644 --- a/docs/codeql/writing-codeql-queries/find-the-thief.rst +++ b/docs/codeql/writing-codeql-queries/find-the-thief.rst @@ -50,9 +50,7 @@ You start asking some creative questions and making notes of the answers so you There is too much information to search through by hand, so you decide to use your newly acquired QL skills to help you with your investigation... -#. Open the `query console on LGTM.com `__ to get started. -#. Select a language and a demo project. For this tutorial, any language and project will do. -#. Delete the default code ``import select "hello world"``. +.. include:: ../reusables/setup-to-run-tutorials.rst QL libraries ------------ @@ -209,13 +207,7 @@ Hints Once you have finished, you will have a list of possible suspects. One of those people must be the thief! -➤ `See the answer in the query console on LGTM.com `__ - -.. pull-quote:: - - Note - - In the answer, we used ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is just a *comment*. +➤ `Check your answer <#exercise-1>`__ You are getting closer to solving the mystery! Unfortunately, you still have quite a long list of suspects... To find out which of your suspects is the thief, you must gather more information and refine your query in the next step. @@ -291,9 +283,59 @@ You can now translate the remaining questions into QL: Have you found the thief? -➤ `See the answer in the query console on LGTM.com `__ +➤ `Check your answer <#exercise-2>`__ Further reading --------------- .. include:: ../reusables/codeql-ref-tools-further-reading.rst + + +-------------- + +Answers +------- + +In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*. + +Exercise 1 +^^^^^^^^^^ + +.. code-block:: ql + + import tutorial + + from Person t + where + /* 1 */ t.getHeight() > 150 and + /* 2 */ not t.getHairColor() = "blond" and + /* 3 */ exists (string c | t.getHairColor() = c) and + /* 4 */ not t.getAge() < 30 and + /* 5 */ t.getLocation() = "east" and + /* 6 */ (t.getHairColor() = "black" or t.getHairColor() = "brown") and + /* 7 */ not (t.getHeight() > 180 and t.getHeight() < 190) and + /* 8 */ exists(Person p | p.getAge() > t.getAge()) + select t + +Exercise 2 +^^^^^^^^^^ + +.. code-block:: ql + + import tutorial + + from Person t + where + /* 1 */ t.getHeight() > 150 and + /* 2 */ not t.getHairColor() = "blond" and + /* 3 */ exists (string c | t.getHairColor() = c) and + /* 4 */ not t.getAge() < 30 and + /* 5 */ t.getLocation() = "east" and + /* 6 */ (t.getHairColor() = "black" or t.getHairColor() = "brown") and + /* 7 */ not (t.getHeight() > 180 and t.getHeight() < 190) and + /* 8 */ exists(Person p | p.getAge() > t.getAge()) and + /* 9 */ not t = max(Person p | | p order by p.getHeight()) and + /* 10 */ t.getHeight() < avg(float i | exists(Person p | p.getHeight() = i) | i) and + /* 11 */ t = max(Person p | p.getLocation() = "east" | p order by p.getAge()) + select "The thief is " + t + "!" + \ No newline at end of file diff --git a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst index 040f873d410..54cfd20bba7 100644 --- a/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst @@ -9,7 +9,7 @@ About query metadata -------------------- Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a QLDoc comment. -This metadata tells LGTM and the CodeQL :ref:`extension for VS Code ` how to handle the query and display its results correctly. +This metadata tells the CodeQL :ref:`extension for VS Code ` and the `Code scanning feature in GitHub `__ how to handle the query and display its results correctly. It also gives other users information about what the query results mean. For more information on query metadata, see the `query metadata style guide `__ in our `open source repository `__ on GitHub. .. pull-quote:: @@ -28,7 +28,7 @@ The following properties are supported by all query files: +=======================+===========================+=======================================================================================================================================================================================================================================================================================================================================================================+ | ``@description`` | ```` | A sentence or short paragraph to describe the purpose of the query and *why* the result is useful or important. The description is written in plain text, and uses single quotes (``'``) to enclose code elements. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``/``. | +| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard CodeQL queries have the following format: ``/``. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``) or a path (``@kind path-problem``). For more information on these query types, see ":doc:`About CodeQL queries `." | | | | ``path-problem`` | | @@ -40,12 +40,12 @@ The following properties are supported by all query files: | | | ``readability`` | | | | | ``security`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines whether the results are displayed by default on LGTM. | +| ``@precision`` | | ``low`` | Indicates the percentage of query results that are true positives (as opposed to false positive results). This, along with the ``@problem.severity`` property, determines how the results are displayed on GitHub. | | | | ``medium`` | | | | | ``high`` | | | | | ``very-high`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines whether the results are displayed by default on LGTM. | +| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed on GitHub. | | | | ``warning`` | | | | | ``recommendation`` | | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst b/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst index 239d3fc7628..f8f5682c8b9 100644 --- a/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst @@ -11,7 +11,7 @@ CodeQL includes mechanisms for extracting the location of elements in a codebase About locations --------------- -When displaying information to the user, LGTM needs to be able to extract location information from the results of a query. In order to do this, all QL classes which can provide location information should do this by using one of the following mechanisms: +When displaying information to the user, applications need to be able to extract location information from the results of a query. In order to do this, all QL classes which can provide location information should do this by using one of the following mechanisms: - `Providing URLs <#providing-urls>`__ - `Providing location information <#providing-location-information>`__ @@ -49,7 +49,7 @@ A custom URL can be provided by defining a QL predicate returning ``string`` wit File URLs ^^^^^^^^^ -LGTM supports the display of URLs which define a line and column in a source file. +The CodeQL extension for Visual Studio Code and the code scanning views in GitHub support the display of URLs which define a line and column in a source file. The schema is ``file://``, which is followed by the absolute path to a file, followed by four numbers separated by colons. The numbers denote start line, start column, end line and end column. Both line and column numbers are **1-based**, for example: @@ -57,12 +57,12 @@ The schema is ``file://``, which is followed by the absolute path to a file, fol - ``file:///opt/src/my/file.java:1:1:2:1`` denotes the location that starts at the beginning of the file and extends to the first character of the second line (the range is inclusive). - ``file:///opt/src/my/file.java:1:0:1:0`` is taken, by convention, to denote the entire first line of the file. -By convention, the location of an entire file may also be denoted by a ``file://`` URL without trailing numbers. Optionally, the location within a file can be denoted using three numbers to define the start line number, character offset and character length of the location respectively. Results of these types are not displayed in LGTM. +By convention, the location of an entire file may also be denoted by a ``file://`` URL without trailing numbers. Optionally, the location within a file can be denoted using three numbers to define the start line number, character offset and character length of the location respectively. Results of these types are not displayed as code scanning alerts. Other types of URL ^^^^^^^^^^^^^^^^^^ -The following, less-common types of URL are valid but are not supported by LGTM and will be omitted from any results: +The following, less-common types of URL are valid but are not interpreted as code scanning alerts and will be omitted from any results: - **HTTP URLs** are supported in some client applications. For an example, see the code snippet above. - **Folder URLs** can be useful, for example to provide folder-level metrics. They may use a file URL, for example ``file:///opt/src:0:0:0:0``, but they may also start with a scheme of ``folder://``, and no trailing numbers, for example ``folder:///opt/src``. diff --git a/docs/codeql/writing-codeql-queries/river-answer-1-path.ql b/docs/codeql/writing-codeql-queries/river-answer-1-path.ql new file mode 100644 index 00000000000..49b1b95856f --- /dev/null +++ b/docs/codeql/writing-codeql-queries/river-answer-1-path.ql @@ -0,0 +1,110 @@ +/** + * A solution to the river crossing puzzle using a modified `path` variable + * to describe the resulting path in detail. + */ + +/** A possible cargo item. */ +class Cargo extends string { + Cargo() { this = ["Nothing", "Goat", "Cabbage", "Wolf"] } +} + +/** A shore, named either `Left` or `Right`. */ +class Shore extends string { + Shore() { + this = "Left" or + this = "Right" + } + + /** Returns the other shore. */ + Shore other() { + this = "Left" and result = "Right" + or + this = "Right" and result = "Left" + } +} + +/** Renders the state as a string. */ +string renderState(Shore manShore, Shore goatShore, Shore cabbageShore, Shore wolfShore) { + result = manShore + "," + goatShore + "," + cabbageShore + "," + wolfShore +} + +/** A record of where everything is. */ +class State extends string { + Shore manShore; + Shore goatShore; + Shore cabbageShore; + Shore wolfShore; + + State() { this = renderState(manShore, goatShore, cabbageShore, wolfShore) } + + /** Returns the state that is reached after ferrying a particular cargo item. */ + State ferry(Cargo cargo) { + cargo = "Nothing" and + result = renderState(manShore.other(), goatShore, cabbageShore, wolfShore) + or + cargo = "Goat" and + result = renderState(manShore.other(), goatShore.other(), cabbageShore, wolfShore) + or + cargo = "Cabbage" and + result = renderState(manShore.other(), goatShore, cabbageShore.other(), wolfShore) + or + cargo = "Wolf" and + result = renderState(manShore.other(), goatShore, cabbageShore, wolfShore.other()) + } + + /** + * Holds if the state is safe. This occurs when neither the goat nor the cabbage + * can get eaten. + */ + predicate isSafe() { + // The goat can't eat the cabbage. + (goatShore != cabbageShore or goatShore = manShore) and + // The wolf can't eat the goat. + (wolfShore != goatShore or wolfShore = manShore) + } + + /** Returns the state that is reached after safely ferrying a cargo item. */ + State safeFerry(Cargo cargo) { result = this.ferry(cargo) and result.isSafe() } + + string towards() { + manShore = "Left" and result = "to the left" + or + manShore = "Right" and result = "to the right" + } + + /** + * Returns all states that are reachable via safe ferrying. + * `path` keeps track of how it is achieved. + * `visitedStates` keeps track of previously visited states and is used to avoid loops. + */ + State reachesVia(string path, string visitedStates) { + // Reachable in 1 step by ferrying a specific cargo + exists(Cargo cargo | + result = this.safeFerry(cargo) and + visitedStates = result and + path = "First " + cargo + " is ferried " + result.towards() + ) + or + // Reachable by first following pathSoFar and then ferrying cargo + exists(string pathSoFar, string visitedStatesSoFar, Cargo cargo | + result = this.reachesVia(pathSoFar, visitedStatesSoFar).safeFerry(cargo) and + not exists(visitedStatesSoFar.indexOf(result)) and // resulting state is not visited yet + visitedStates = visitedStatesSoFar + "_" + result and + path = pathSoFar + ",\nthen " + cargo + " is ferried " + result.towards() + ) + } +} + +/** The initial state, where everything is on the left shore. */ +class InitialState extends State { + InitialState() { this = renderState("Left", "Left", "Left", "Left") } +} + +/** The goal state, where everything is on the right shore. */ +class GoalState extends State { + GoalState() { this = renderState("Right", "Right", "Right", "Right") } +} + +from string path +where any(InitialState i).reachesVia(path, _) = any(GoalState g) +select path + "." diff --git a/docs/codeql/writing-codeql-queries/river-answer-2-abstract-class.ql b/docs/codeql/writing-codeql-queries/river-answer-2-abstract-class.ql new file mode 100644 index 00000000000..55614f7e856 --- /dev/null +++ b/docs/codeql/writing-codeql-queries/river-answer-2-abstract-class.ql @@ -0,0 +1,202 @@ +/** + * A solution to the river crossing puzzle using abstract + * classes/predicates to model the situation and unicode + * symbols to display the answer. + */ + +/** One of two shores. */ +class Shore extends string { + Shore() { this = "left" or this = "right" } +} + +/** Models the behavior of the man. */ +class Man extends string { + Shore s; + + Man() { this = "man " + s } + + /** Holds if the man is on a particular shore. */ + predicate isOn(Shore shore) { s = shore } + + /** Returns the other shore, after the man crosses the river. */ + Man cross() { result != this } + + /** Returns a cargo and its position after being ferried. */ + Cargo ferry(Cargo c) { + result = c.cross() and + c.isOn(s) + } +} + +/** One of three possible cargo items, with their position. */ +abstract class Cargo extends string { + Shore s; + + bindingset[this] + Cargo() { any() } + + /** Holds if the cargo is on a particular shore. */ + predicate isOn(Shore shore) { s = shore } + + /** Returns the other shore, after the cargo crosses the river. */ + abstract Cargo cross(); +} + +/** Models the position of the goat. */ +class Goat extends Cargo { + Goat() { this = "goat " + s } + + override Goat cross() { result != this } +} + +/** Models the position of the wolf. */ +class Wolf extends Cargo { + Wolf() { this = "wolf " + s } + + override Wolf cross() { result != this } +} + +/** Models the position of the cabbage. */ +class Cabbage extends Cargo { + Cabbage() { this = "cabbage " + s } + + override Cabbage cross() { result != this } +} + +/** Returns a unicode representation of everything on the left shore. */ +string onLeft(Man man, Goat goat, Cabbage cabbage, Wolf wolf) { + exists(string manOnLeft, string goatOnLeft, string cabbageOnLeft, string wolfOnLeft | + ( + man.isOn("left") and manOnLeft = "🕴" + or + man.isOn("right") and manOnLeft = "____" + ) and + ( + goat.isOn("left") and goatOnLeft = "🐐" + or + goat.isOn("right") and goatOnLeft = "___" + ) and + ( + cabbage.isOn("left") and cabbageOnLeft = "🥬" + or + cabbage.isOn("right") and cabbageOnLeft = "___" + ) and + ( + wolf.isOn("left") and wolfOnLeft = "🐺" + or + wolf.isOn("right") and wolfOnLeft = "___" + ) and + result = manOnLeft + "__" + goatOnLeft + "__" + cabbageOnLeft + "__" + wolfOnLeft + ) +} + +/** Returns a unicode representation of everything on the right shore. */ +string onRight(Man man, Goat goat, Cabbage cabbage, Wolf wolf) { + exists(string manOnLeft, string goatOnLeft, string cabbageOnLeft, string wolfOnLeft | + ( + man.isOn("right") and manOnLeft = "🕴" + or + man.isOn("left") and manOnLeft = "_" + ) and + ( + goat.isOn("right") and goatOnLeft = "🐐" + or + goat.isOn("left") and goatOnLeft = "__" + ) and + ( + cabbage.isOn("right") and cabbageOnLeft = "🥬" + or + cabbage.isOn("left") and cabbageOnLeft = "__" + ) and + ( + wolf.isOn("right") and wolfOnLeft = "🐺" + or + wolf.isOn("left") and wolfOnLeft = "__" + ) and + result = manOnLeft + "__" + goatOnLeft + "__" + cabbageOnLeft + "__" + wolfOnLeft + ) +} + +/** Renders the state as a string, using unicode symbols. */ +string render(Man man, Goat goat, Cabbage cabbage, Wolf wolf) { + result = + onLeft(man, goat, cabbage, wolf) + "___🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊___" + + onRight(man, goat, cabbage, wolf) +} + +/** A record of where everything is. */ +class State extends string { + Man man; + Goat goat; + Cabbage cabbage; + Wolf wolf; + + State() { this = render(man, goat, cabbage, wolf) } + + /** + * Returns the possible states that you can transition to + * by ferrying one or zero cargo items. + */ + State transition() { + result = render(man.cross(), man.ferry(goat), cabbage, wolf) or + result = render(man.cross(), goat, man.ferry(cabbage), wolf) or + result = render(man.cross(), goat, cabbage, man.ferry(wolf)) or + result = render(man.cross(), goat, cabbage, wolf) + } + + /** + * Returns all states that are reachable via a transition + * and have not yet been visited. + * `path` keeps track of how it is achieved. + */ + State reachesVia(string path) { + exists(string pathSoFar | + result = this.reachesVia(pathSoFar).transition() and + not exists(pathSoFar.indexOf(result.toString())) and + path = pathSoFar + "\n↓\n" + result + ) + } +} + +/** The initial state, where everything is on the left shore. */ +class InitialState extends State { + InitialState() { + exists(Shore left | left = "left" | + man.isOn(left) and goat.isOn(left) and cabbage.isOn(left) and wolf.isOn(left) + ) + } + + override State reachesVia(string path) { + path = this + "\n↓\n" + result and result = this.transition() + or + result = super.reachesVia(path) + } +} + +/** The goal state, where everything is on the right shore. */ +class GoalState extends State { + GoalState() { + exists(Shore right | right = "right" | + man.isOn(right) and goat.isOn(right) and cabbage.isOn(right) and wolf.isOn(right) + ) + } + + override State transition() { none() } +} + +/** An unsafe state, where something gets eaten. */ +class IllegalState extends State { + IllegalState() { + exists(Shore s | + goat.isOn(s) and cabbage.isOn(s) and not man.isOn(s) + or + wolf.isOn(s) and goat.isOn(s) and not man.isOn(s) + ) + } + + override State transition() { none() } +} + +from string path +where any(InitialState i).reachesVia(path) = any(GoalState g) +select path diff --git a/docs/codeql/writing-codeql-queries/river-answer-3-datatypes.ql b/docs/codeql/writing-codeql-queries/river-answer-3-datatypes.ql new file mode 100644 index 00000000000..bb74a0321b9 --- /dev/null +++ b/docs/codeql/writing-codeql-queries/river-answer-3-datatypes.ql @@ -0,0 +1,169 @@ +/** + * "Typesafe" solution to the river crossing puzzle. + */ + +/** Either the left shore or the right shore. */ +newtype TShore = + Left() or + Right() + +class Shore extends TShore { + Shore other() { result != this } + + string toString() { + this = Left() and result = "left" + or + this = Right() and result = "right" + } +} + +newtype TMan = TManOn(Shore s) + +/** Models the behavior of the man. */ +class Man extends TMan { + Shore s; + + Man() { this = TManOn(s) } + + /** Holds if the man is on a particular shore. */ + predicate isOn(Shore shore) { s = shore } + + /** Returns the other shore, after the man crosses the river. */ + Man cross() { result.isOn(s.other()) } + + /** Returns a cargo and its position after being ferried. */ + Cargo ferry(Cargo c) { + result = c.cross() and + c.isOn(s) + } + + string toString() { result = "man " + s } +} + +newtype TCargo = + TGoat(Shore s) or + TCabbage(Shore s) or + TWolf(Shore s) + +/** One of three possible cargo items, with their position. */ +abstract class Cargo extends TCargo { + Shore s; + + /** Holds if the cargo is on a particular shore. */ + predicate isOn(Shore shore) { s = shore } + + /** Returns the other shore, after the cargo crosses the river. */ + abstract Cargo cross(); + + abstract string toString(); +} + +/** Models the position of the goat. */ +class Goat extends Cargo, TGoat { + Goat() { this = TGoat(s) } + + override Cargo cross() { result = TGoat(s.other()) } + + override string toString() { result = "goat " + s } +} + +/** Models the position of the wolf. */ +class Wolf extends Cargo, TWolf { + Wolf() { this = TWolf(s) } + + override Cargo cross() { result = TWolf(s.other()) } + + override string toString() { result = "wolf " + s } +} + +/** Models the position of the cabbage. */ +class Cabbage extends Cargo, TCabbage { + Cabbage() { this = TCabbage(s) } + + override Cargo cross() { result = TCabbage(s.other()) } + + override string toString() { result = "cabbage " + s } +} + +newtype TState = Currently(Man man, Goat goat, Cabbage cabbage, Wolf wolf) + +/** A record of where everything is. */ +class State extends TState { + Man man; + Goat goat; + Cabbage cabbage; + Wolf wolf; + + State() { this = Currently(man, goat, cabbage, wolf) } + + /** + * Returns the possible states that you can transition to + * by ferrying one or zero cargo items. + */ + State transition() { + result = Currently(man.cross(), man.ferry(goat), cabbage, wolf) or + result = Currently(man.cross(), goat, man.ferry(cabbage), wolf) or + result = Currently(man.cross(), goat, cabbage, man.ferry(wolf)) or + result = Currently(man.cross(), goat, cabbage, wolf) + } + + /** + * Returns all states that are reachable via a transition + * and have not yet been visited. + * `path` keeps track of how it is achieved. + */ + State reachesVia(string path) { + exists(string pathSoFar | + result = this.reachesVia(pathSoFar).transition() and + not exists(pathSoFar.indexOf(result.toString())) and + path = pathSoFar + "\n" + result + ) + } + + string toString() { result = man + "/" + goat + "/" + cabbage + "/" + wolf } +} + +/** The initial state, where everything is on the left shore. */ +class InitialState extends State { + InitialState() { + man.isOn(Left()) and goat.isOn(Left()) and cabbage.isOn(Left()) and wolf.isOn(Left()) + } + + override State reachesVia(string path) { + path = this + "\n" + result and result = this.transition() + or + result = super.reachesVia(path) + } + + override string toString() { result = "Initial: " + super.toString() } +} + +/** The goal state, where everything is on the right shore. */ +class GoalState extends State { + GoalState() { + man.isOn(Right()) and goat.isOn(Right()) and cabbage.isOn(Right()) and wolf.isOn(Right()) + } + + override State transition() { none() } + + override string toString() { result = "Goal: " + super.toString() } +} + +/** An unsafe state, where something gets eaten. */ +class IllegalState extends State { + IllegalState() { + exists(Shore s | + goat.isOn(s) and cabbage.isOn(s) and not man.isOn(s) + or + wolf.isOn(s) and goat.isOn(s) and not man.isOn(s) + ) + } + + override State transition() { none() } + + override string toString() { result = "ILLEGAL: " + super.toString() } +} + +from string path +where any(InitialState i).reachesVia(path) = any(GoalState g) +select path diff --git a/docs/codeql/writing-codeql-queries/river-crossing-1.ql b/docs/codeql/writing-codeql-queries/river-crossing-1.ql index 80d828c7389..b9774404a5a 100644 --- a/docs/codeql/writing-codeql-queries/river-crossing-1.ql +++ b/docs/codeql/writing-codeql-queries/river-crossing-1.ql @@ -99,4 +99,3 @@ class GoalState extends State { from string path where any(InitialState i).reachesVia(path, _) = any(GoalState g) select path - diff --git a/docs/prepare-db-upgrade.md b/docs/prepare-db-upgrade.md index 906c47d9c6d..42c329dd947 100644 --- a/docs/prepare-db-upgrade.md +++ b/docs/prepare-db-upgrade.md @@ -69,10 +69,10 @@ Although we have some automated testing of the scripts (e.g. to test that you ca To test the upgrade script, run: ``` -codeql test run --search-path= --search-path=ql +codeql test run --search-path= --search-path= ``` -Where `` is an extractor pack containing the old extractor and dbscheme that pre-date your changes, and `` is the directory containing the qltests for your language. This will run the tests using an old extractor, and the test databases will all be upgraded in place using your new upgrade script. +Where `` is an extractor pack containing the old extractor and dbscheme that pre-date your changes, `` is the directory containing the qltests for your language, and `` is the root directory directory of the `github/codeql` clone that contains ``. This will run the tests using an old extractor, and the test databases will all be upgraded in place using your new upgrade script. To test the downgrade script, create an extractor pack that includes your new dbscheme and extractor changes. Then checkout the `main` branch of `codeql` (i.e. a branch that does not include your changes), and run: diff --git a/docs/ql-style-guide.md b/docs/ql-style-guide.md index 0b0efef27cc..29a427fdfae 100644 --- a/docs/ql-style-guide.md +++ b/docs/ql-style-guide.md @@ -176,7 +176,7 @@ private predicate foo(Expr e, Expr p) { 1. Acronyms *should* use normal PascalCase/camelCase. However, two-letter acronyms should have both letters capitalized. 1. Newtype predicate names *should* begin with `T`. 1. Predicates that have a result *should* be named `get...` -1. Predicates that can return multiple results *should* be named `getA...` or `getAn...` +1. Predicates that can have multiple results *should* be named `getA...` or `getAn...` 1. Predicates that don't have a result or parameters *should* be named `is...` or `has...` 1. *Avoid* underscores in names. 1. *Avoid* short or single-letter names for classes, predicates and fields. @@ -304,6 +304,7 @@ For more information about documenting the code that you contribute to this repo exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter) ``` + ```ql exists(Type qualifierType | this.hasNonExactQualifierType(qualifierType) diff --git a/go/Makefile b/go/Makefile index 419b1991775..4faf28c41ea 100644 --- a/go/Makefile +++ b/go/Makefile @@ -34,7 +34,6 @@ autoformat: find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -w check-formatting: - find ql -iregex '.*\.qll?' -print0 | xargs -0 codeql query format --check-only test -z "$$(find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -l)" install-deps: @@ -84,6 +83,7 @@ extractor-common: codeql-extractor.yml LICENSE ql/lib/go.dbscheme \ cp codeql-extractor.yml LICENSE ql/lib/go.dbscheme ql/lib/go.dbscheme.stats $(EXTRACTOR_PACK_OUT) mkdir $(EXTRACTOR_PACK_OUT)/tools cp -r tools/tokenizer.jar $(CODEQL_TOOLS) $(EXTRACTOR_PACK_OUT)/tools + cp -r downgrades $(EXTRACTOR_PACK_OUT) extractor: extractor-common tools-codeql cp -r tools/$(CODEQL_PLATFORM) $(EXTRACTOR_PACK_OUT)/tools @@ -117,9 +117,9 @@ ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor codeql dataset measure -o $@ build/stats/database/db-go test: all build/testdb/check-upgrade-path - codeql test run ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + codeql test run -j0 ql/test --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) # use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported - env GOOS=linux GOARCH=386 codeql$(EXE) test run ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency + env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path build/codeql-extractor-go --consistency-queries ql/test/consistency --compilation-cache=$(cache) cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]" bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1) @@ -133,10 +133,3 @@ build/testdb/go.dbscheme: ql/lib/upgrades/initial/go.dbscheme rm -rf build/testdb echo >build/empty.trap codeql dataset import -S ql/lib/upgrades/initial/go.dbscheme build/testdb build/empty.trap - -.PHONY: sync-dataflow-libraries -sync-dataflow-libraries: - for f in DataFlowImpl.qll DataFlowImpl2.qll DataFlowImplCommon.qll DataFlowImplConsistency.qll tainttracking1/TaintTrackingImpl.qll tainttracking2/TaintTrackingImpl.qll FlowSummaryImpl.qll AccessPathSyntax.qll;\ - do\ - curl -s -o ./ql/lib/semmle/go/dataflow/internal/$$f https://raw.githubusercontent.com/github/codeql/$(DATAFLOW_BRANCH)/java/ql/lib/semmle/code/java/dataflow/internal/$$f;\ - done diff --git a/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/go.dbscheme b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/go.dbscheme new file mode 100644 index 00000000000..90fa7836e0a --- /dev/null +++ b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/go.dbscheme @@ -0,0 +1,547 @@ +/** Auto-generated dbscheme; do not edit. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @namedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int named: @namedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr +| 55 = @errorexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @namedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @namedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/old.dbscheme b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/old.dbscheme new file mode 100644 index 00000000000..a58b81b1b4c --- /dev/null +++ b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/old.dbscheme @@ -0,0 +1,546 @@ +/** Auto-generated dbscheme; do not edit. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @namedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int named: @namedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @namedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @namedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/upgrade.properties b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/upgrade.properties new file mode 100644 index 00000000000..4982fc6893a --- /dev/null +++ b/go/downgrades/a58b81b1b4c4cccc8ca11731c1db86622f33af57/upgrade.properties @@ -0,0 +1,2 @@ +description: Delete @errorexpr - @badexpr should be used instead +compatibility: full diff --git a/go/extractor/dbscheme/tables.go b/go/extractor/dbscheme/tables.go index 63332aa3b59..e987cb402ae 100644 --- a/go/extractor/dbscheme/tables.go +++ b/go/extractor/dbscheme/tables.go @@ -521,9 +521,6 @@ var ChanTypeExprs = map[ast.ChanDir]*BranchType{ ast.SEND | ast.RECV: ExprKind.NewBranch("@sendrcvchantypeexpr", ChanTypeExpr), } -// ErrorExpr is an AST node type that is not used anywhere -var ErrorExpr = ExprKind.NewBranch("@errorexpr") - // StmtKind is a case type for distinguishing different kinds of statement AST nodes var StmtKind = NewCaseType(StmtType, "kind") diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index 1be2bfef224..4b087d82947 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -103,29 +103,29 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { extractUniverseScope() log.Println("Done extracting universe scope.") - // a map of package path to package root directory (currently the module root or the source directory) - pkgRoots := make(map[string]string) - // a map of package path to source code directory - pkgDirs := make(map[string]string) + // a map of package path to source directory and module root directory + pkgInfos := make(map[string]util.PkgInfo) // root directories of packages that we want to extract wantedRoots := make(map[string]bool) + if os.Getenv("CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO") != "" { + log.Printf("Running go list to resolve package and module directories.") + // get all packages information + pkgInfos, err = util.GetPkgsInfo(patterns, true, modFlags...) + if err != nil { + log.Fatalf("Error getting dependency package or module directories: %v.", err) + } + log.Printf("Done running go list deps: resolved %d packages.", len(pkgInfos)) + } + // Do a post-order traversal and extract the package scope of each package packages.Visit(pkgs, func(pkg *packages.Package) bool { return true }, func(pkg *packages.Package) { log.Printf("Processing package %s.", pkg.PkgPath) - if _, ok := pkgRoots[pkg.PkgPath]; !ok { - mdir := util.GetModDir(pkg.PkgPath, modFlags...) - pdir := util.GetPkgDir(pkg.PkgPath, modFlags...) - // GetModDir returns the empty string if the module directory cannot be determined, e.g. if the package - // is not using modules. If this is the case, fall back to the package directory - if mdir == "" { - mdir = pdir - } - pkgRoots[pkg.PkgPath] = mdir - pkgDirs[pkg.PkgPath] = pdir + if _, ok := pkgInfos[pkg.PkgPath]; !ok { + pkgInfos[pkg.PkgPath] = util.GetPkgInfo(pkg.PkgPath, modFlags...) } log.Printf("Extracting types for package %s.", pkg.PkgPath) @@ -152,11 +152,14 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { }) for _, pkg := range pkgs { - if pkgRoots[pkg.PkgPath] == "" { + pkgInfo, ok := pkgInfos[pkg.PkgPath] + if !ok || pkgInfo.PkgDir == "" { log.Fatalf("Unable to get a source directory for input package %s.", pkg.PkgPath) } - wantedRoots[pkgRoots[pkg.PkgPath]] = true - wantedRoots[pkgDirs[pkg.PkgPath]] = true + wantedRoots[pkgInfo.PkgDir] = true + if pkgInfo.ModDir != "" { + wantedRoots[pkgInfo.ModDir] = true + } } log.Println("Done processing dependencies.") @@ -174,7 +177,8 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { return true }, func(pkg *packages.Package) { for root, _ := range wantedRoots { - relDir, err := filepath.Rel(root, pkgDirs[pkg.PkgPath]) + pkgInfo := pkgInfos[pkg.PkgPath] + relDir, err := filepath.Rel(root, pkgInfo.PkgDir) if err != nil || noExtractRe.MatchString(relDir) { // if the path can't be made relative or matches the noExtract regexp skip it continue @@ -182,8 +186,12 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { extraction.extractPackage(pkg) - if pkgRoots[pkg.PkgPath] != "" { - modPath := filepath.Join(pkgRoots[pkg.PkgPath], "go.mod") + modDir := pkgInfo.ModDir + if modDir == "" { + modDir = pkgInfo.PkgDir + } + if modDir != "" { + modPath := filepath.Join(modDir, "go.mod") if util.FileExists(modPath) { log.Printf("Extracting %s", modPath) start := time.Now() diff --git a/go/extractor/trap/labels.go b/go/extractor/trap/labels.go index 1e9bd298447..f1572fb874e 100644 --- a/go/extractor/trap/labels.go +++ b/go/extractor/trap/labels.go @@ -57,7 +57,7 @@ func (l *Labeler) GlobalID(key string) Label { label, exists := l.keyLabels[key] if !exists { id := l.nextID() - fmt.Fprintf(l.tw.zip, "%s=@\"%s\"\n", id, escapeString(key)) + fmt.Fprintf(l.tw.wzip, "%s=@\"%s\"\n", id, escapeString(key)) label = Label{id} l.keyLabels[key] = label } @@ -90,7 +90,7 @@ func (l *Labeler) LocalID(nd interface{}) Label { // FreshID creates a fresh label and returns it func (l *Labeler) FreshID() Label { id := l.nextID() - fmt.Fprintf(l.tw.zip, "%s=*\n", id) + fmt.Fprintf(l.tw.wzip, "%s=*\n", id) return Label{id} } diff --git a/go/extractor/trap/trapwriter.go b/go/extractor/trap/trapwriter.go index 4c0911e24d7..0833d845830 100644 --- a/go/extractor/trap/trapwriter.go +++ b/go/extractor/trap/trapwriter.go @@ -19,7 +19,8 @@ import ( // A Writer provides methods for writing data to a TRAP file type Writer struct { zip *gzip.Writer - w *bufio.Writer + wzip *bufio.Writer + wfile *bufio.Writer file *os.File Labeler *Labeler path string @@ -54,11 +55,13 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) { if err != nil { return nil, err } - bufioWriter := bufio.NewWriter(tmpFile) - zipWriter := gzip.NewWriter(bufioWriter) + bufioFileWriter := bufio.NewWriter(tmpFile) + zipWriter := gzip.NewWriter(bufioFileWriter) + bufioZipWriter := bufio.NewWriter(zipWriter) tw := &Writer{ zipWriter, - bufioWriter, + bufioZipWriter, + bufioFileWriter, tmpFile, nil, path, @@ -88,13 +91,19 @@ func trapFolder() (string, error) { // Close the underlying file writer func (tw *Writer) Close() error { - err := tw.zip.Close() + err := tw.wzip.Flush() + if err != nil { + // throw away file close error + tw.file.Close() + return err + } + err = tw.zip.Close() if err != nil { // return zip-close error, but ignore file-close error tw.file.Close() return err } - err = tw.w.Flush() + err = tw.wfile.Flush() if err != nil { // throw away close error because write errors are likely to be more important tw.file.Close() @@ -145,24 +154,24 @@ func capStringLength(s string) string { // Emit writes out a tuple of values for the given `table` func (tw *Writer) Emit(table string, values []interface{}) error { - fmt.Fprintf(tw.zip, "%s(", table) + fmt.Fprintf(tw.wzip, "%s(", table) for i, value := range values { if i > 0 { - fmt.Fprint(tw.zip, ", ") + fmt.Fprint(tw.wzip, ", ") } switch value := value.(type) { case Label: - fmt.Fprint(tw.zip, value.id) + fmt.Fprint(tw.wzip, value.id) case string: - fmt.Fprintf(tw.zip, "\"%s\"", escapeString(capStringLength(value))) + fmt.Fprintf(tw.wzip, "\"%s\"", escapeString(capStringLength(value))) case int: - fmt.Fprintf(tw.zip, "%d", value) + fmt.Fprintf(tw.wzip, "%d", value) case float64: - fmt.Fprintf(tw.zip, "%e", value) + fmt.Fprintf(tw.wzip, "%e", value) default: return errors.New("Cannot emit value") } } - fmt.Fprintf(tw.zip, ")\n") + fmt.Fprintf(tw.wzip, ")\n") return nil } diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index 5725c03d5b6..c4bdf3d1c61 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -1,7 +1,9 @@ package util import ( + "encoding/json" "errors" + "io" "log" "os" "os/exec" @@ -31,13 +33,13 @@ func Getenv(key string, aliases ...string) string { // runGoList is a helper function for running go list with format `format` and flags `flags` on // package `pkgpath`. -func runGoList(format string, pkgpath string, flags ...string) (string, error) { - return runGoListWithEnv(format, pkgpath, nil, flags...) +func runGoList(format string, patterns []string, flags ...string) (string, error) { + return runGoListWithEnv(format, patterns, nil, flags...) } -func runGoListWithEnv(format string, pkgpath string, additionalEnv []string, flags ...string) (string, error) { +func runGoListWithEnv(format string, patterns []string, additionalEnv []string, flags ...string) (string, error) { args := append([]string{"list", "-e", "-f", format}, flags...) - args = append(args, pkgpath) + args = append(args, patterns...) cmd := exec.Command("go", args...) cmd.Env = append(os.Environ(), additionalEnv...) out, err := cmd.Output() @@ -54,18 +56,89 @@ func runGoListWithEnv(format string, pkgpath string, additionalEnv []string, fla return strings.TrimSpace(string(out)), nil } +// PkgInfo holds package directory and module directory (if any) for a package +type PkgInfo struct { + PkgDir string // the directory directly containing source code of this package + ModDir string // the module directory containing this package, empty if not a module +} + +// GetPkgsInfo gets the absolute module and package root directories for the packages matched by the +// patterns `patterns`. It passes to `go list` the flags specified by `flags`. If `includingDeps` +// is true, all dependencies will also be included. +func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[string]PkgInfo, error) { + // enable module mode so that we can find a module root if it exists, even if go module support is + // disabled by a build + if includingDeps { + // the flag `-deps` causes all dependencies to be retrieved + flags = append(flags, "-deps") + } + + // using -json overrides -f format + output, err := runGoList("", patterns, append(flags, "-json")...) + if err != nil { + return nil, err + } + + // the output of `go list -json` is a stream of json object + type goListPkgInfo struct { + ImportPath string + Dir string + Module *struct { + Dir string + } + } + pkgInfoMapping := make(map[string]PkgInfo) + streamDecoder := json.NewDecoder(strings.NewReader(output)) + for { + var pkgInfo goListPkgInfo + decErr := streamDecoder.Decode(&pkgInfo) + if decErr == io.EOF { + break + } + if decErr != nil { + log.Printf("Error decoding output of go list -json: %s", err.Error()) + return nil, decErr + } + pkgAbsDir, err := filepath.Abs(pkgInfo.Dir) + if err != nil { + log.Printf("Unable to make package dir %s absolute: %s", pkgInfo.Dir, err.Error()) + } + var modAbsDir string + if pkgInfo.Module != nil { + modAbsDir, err = filepath.Abs(pkgInfo.Module.Dir) + if err != nil { + log.Printf("Unable to make module dir %s absolute: %s", pkgInfo.Module.Dir, err.Error()) + } + } + pkgInfoMapping[pkgInfo.ImportPath] = PkgInfo{ + PkgDir: pkgAbsDir, + ModDir: modAbsDir, + } + } + return pkgInfoMapping, nil +} + +// GetPkgInfo fills the package info structure for the specified package path. +// It passes the `go list` the flags specified by `flags`. +func GetPkgInfo(pkgpath string, flags ...string) PkgInfo { + return PkgInfo{ + PkgDir: GetPkgDir(pkgpath, flags...), + ModDir: GetModDir(pkgpath, flags...), + } +} + // GetModDir gets the absolute directory of the module containing the package with path // `pkgpath`. It passes the `go list` the flags specified by `flags`. func GetModDir(pkgpath string, flags ...string) string { // enable module mode so that we can find a module root if it exists, even if go module support is // disabled by a build - mod, err := runGoListWithEnv("{{.Module}}", pkgpath, []string{"GO111MODULE=on"}, flags...) + mod, err := runGoListWithEnv("{{.Module}}", []string{pkgpath}, []string{"GO111MODULE=on"}, flags...) if err != nil || mod == "" { // if the command errors or modules aren't being used, return the empty string return "" } - modDir, err := runGoListWithEnv("{{.Module.Dir}}", pkgpath, []string{"GO111MODULE=on"}, flags...) + modDir, err := runGoListWithEnv("{{.Module.Dir}}", []string{pkgpath}, []string{"GO111MODULE=on"}, flags...) if err != nil { return "" } @@ -81,7 +154,7 @@ func GetModDir(pkgpath string, flags ...string) string { // GetPkgDir gets the absolute directory containing the package with path `pkgpath`. It passes the // `go list` command the flags specified by `flags`. func GetPkgDir(pkgpath string, flags ...string) string { - pkgDir, err := runGoList("{{.Dir}}", pkgpath, flags...) + pkgDir, err := runGoList("{{.Dir}}", []string{pkgpath}, flags...) if err != nil { return "" } @@ -97,7 +170,7 @@ func GetPkgDir(pkgpath string, flags ...string) string { // DepErrors checks there are any errors resolving dependencies for `pkgpath`. It passes the `go // list` command the flags specified by `flags`. func DepErrors(pkgpath string, flags ...string) bool { - out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", pkgpath, flags...) + out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", []string{pkgpath}, flags...) if err != nil { // if go list failed, assume dependencies are broken return false diff --git a/go/ql/examples/snippets/incompleteswitchoverenum.ql b/go/ql/examples/snippets/incompleteswitchoverenum.ql index b201e55089e..1ded8d0a1ab 100644 --- a/go/ql/examples/snippets/incompleteswitchoverenum.ql +++ b/go/ql/examples/snippets/incompleteswitchoverenum.ql @@ -2,6 +2,7 @@ * @name Incomplete switch over enum * @description A switch statement of enum type should explicitly reference each * of the members of that enum. + * @severity warning * @kind problem * @id go/examples/incomplete-switch */ diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 681412ed46f..ba72eb8950a 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.3.6 + +No user-facing changes. + +## 0.3.5 + +No user-facing changes. + +## 0.3.4 + +No user-facing changes. + ## 0.3.3 No user-facing changes. diff --git a/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md b/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md new file mode 100644 index 00000000000..a796e953583 --- /dev/null +++ b/go/ql/lib/change-notes/2022-11-17-allow-implicit-read-signature.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +The signature of `allowImplicitRead` on `DataFlow::Configuration` and `TaintTracking::Configuration` has changed from `allowImplicitRead(DataFlow::Node node, DataFlow::Content c)` to `allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c)`. diff --git a/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md b/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md new file mode 100644 index 00000000000..2bd95798f89 --- /dev/null +++ b/go/ql/lib/change-notes/2022-11-17-barrierguard-deprecation.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/go/ql/lib/change-notes/2022-11-17-rsync-argument-injection.md b/go/ql/lib/change-notes/2022-11-17-rsync-argument-injection.md new file mode 100644 index 00000000000..fb39aebe09c --- /dev/null +++ b/go/ql/lib/change-notes/2022-11-17-rsync-argument-injection.md @@ -0,0 +1,4 @@ +--- + category: minorAnalysis +--- + * `rsync` has been added to the list of commands which may evaluate its parameters as a shell command. diff --git a/go/ql/lib/change-notes/2022-12-03-gorqlite-goframe.md b/go/ql/lib/change-notes/2022-12-03-gorqlite-goframe.md new file mode 100644 index 00000000000..d86db129dab --- /dev/null +++ b/go/ql/lib/change-notes/2022-12-03-gorqlite-goframe.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Queries that care about SQL, such as `go/sql-injection`, now recognise SQL-consuming functions belonging to the `gorqlite` and `GoFrame` packages. diff --git a/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md b/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md new file mode 100644 index 00000000000..49b42f82eb1 --- /dev/null +++ b/go/ql/lib/change-notes/2022-12-16-implicit-read-flowstates.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed an issue in the taint tracking analysis where implicit reads were not allowed by default in sinks or additional taint steps that used flow states. diff --git a/go/ql/lib/change-notes/2022-12-6-may-have-side-effects-return-stmt.md b/go/ql/lib/change-notes/2022-12-6-may-have-side-effects-return-stmt.md new file mode 100644 index 00000000000..2b885555e5b --- /dev/null +++ b/go/ql/lib/change-notes/2022-12-6-may-have-side-effects-return-stmt.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +The definition of `mayHaveSideEffects` for `ReturnStmt` was incorrect when more +than one expression was being returned. Such return statements were +effectively considered to never have side effects. This has now been fixed. +In rare circumstances `globalValueNumber` may have incorrectly treated two +values as the same when they were in fact distinct. diff --git a/go/ql/lib/change-notes/released/0.3.4.md b/go/ql/lib/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..5fae94b07c9 --- /dev/null +++ b/go/ql/lib/change-notes/released/0.3.4.md @@ -0,0 +1,3 @@ +## 0.3.4 + +No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.3.5.md b/go/ql/lib/change-notes/released/0.3.5.md new file mode 100644 index 00000000000..7a86712e637 --- /dev/null +++ b/go/ql/lib/change-notes/released/0.3.5.md @@ -0,0 +1,3 @@ +## 0.3.5 + +No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.3.6.md b/go/ql/lib/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/go/ql/lib/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 9da182d3394..7bbaa8987dd 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.6 diff --git a/go/ql/lib/go.dbscheme b/go/ql/lib/go.dbscheme index 90fa7836e0a..a58b81b1b4c 100644 --- a/go/ql/lib/go.dbscheme +++ b/go/ql/lib/go.dbscheme @@ -319,8 +319,7 @@ case @expr.kind of | 51 = @andnotexpr | 52 = @sendchantypeexpr | 53 = @recvchantypeexpr -| 54 = @sendrcvchantypeexpr -| 55 = @errorexpr; +| 54 = @sendrcvchantypeexpr; @basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 9daccdd80b6..a3b398f3a0b 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.4-dev +version: 0.4.0-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/lib/semmle/go/Scopes.qll b/go/ql/lib/semmle/go/Scopes.qll index b14d558fabb..385b52028d9 100644 --- a/go/ql/lib/semmle/go/Scopes.qll +++ b/go/ql/lib/semmle/go/Scopes.qll @@ -95,7 +95,12 @@ class Entity extends @object { /** Gets the package in which this entity is declared, if any. */ Package getPackage() { result.getScope() = this.getScope() } - /** Holds if this entity is declared in a package with path `pkg` and has the given `name`. */ + /** + * Holds if this entity is declared in a package with path `pkg` and has the given `name`. + * + * Note that for methods `pkg` is the package path followed by `.` followed + * by the name of the receiver type, for example `io.Writer`. + */ predicate hasQualifiedName(string pkg, string name) { pkg = this.getPackage().getPath() and name = this.getName() diff --git a/go/ql/lib/semmle/go/Stmt.qll b/go/ql/lib/semmle/go/Stmt.qll index 9873bf1db17..2a77450855d 100644 --- a/go/ql/lib/semmle/go/Stmt.qll +++ b/go/ql/lib/semmle/go/Stmt.qll @@ -569,7 +569,7 @@ class ReturnStmt extends @returnstmt, Stmt { /** Gets the unique returned expression, if there is only one. */ Expr getExpr() { getNumChild() = 1 and result = getExpr(0) } - override predicate mayHaveSideEffects() { getExpr().mayHaveSideEffects() } + override predicate mayHaveSideEffects() { getAnExpr().mayHaveSideEffects() } override string toString() { result = "return statement" } diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index 51e03de3ab7..f4f355d87a1 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -106,24 +106,20 @@ module ControlFlow { * A control-flow node that initializes or updates the value of a constant, a variable, * a field, or an (array, slice, or map) element. */ - class WriteNode extends Node { - IR::WriteInstruction self; - - WriteNode() { this = self } - + class WriteNode extends Node instanceof IR::WriteInstruction { /** Gets the left-hand side of this write. */ - IR::WriteTarget getLhs() { result = self.getLhs() } + IR::WriteTarget getLhs() { result = super.getLhs() } /** Gets the right-hand side of this write. */ - DataFlow::Node getRhs() { self.getRhs() = result.asInstruction() } + DataFlow::Node getRhs() { super.getRhs() = result.asInstruction() } /** Holds if this node sets variable or constant `v` to `rhs`. */ - predicate writes(ValueEntity v, DataFlow::Node rhs) { self.writes(v, rhs.asInstruction()) } + predicate writes(ValueEntity v, DataFlow::Node rhs) { super.writes(v, rhs.asInstruction()) } /** Holds if this node defines SSA variable `v` to be `rhs`. */ predicate definesSsaVariable(SsaVariable v, DataFlow::Node rhs) { - self.getLhs().asSsaVariable() = v and - self.getRhs() = rhs.asInstruction() + super.getLhs().asSsaVariable() = v and + super.getRhs() = rhs.asInstruction() } /** @@ -136,13 +132,13 @@ module ControlFlow { * node corresponding to `newWidth`. */ predicate writesField(DataFlow::Node base, Field f, DataFlow::Node rhs) { - exists(IR::FieldTarget trg | trg = self.getLhs() | + exists(IR::FieldTarget trg | trg = super.getLhs() | ( trg.getBase() = base.asInstruction() or trg.getBase() = MkImplicitDeref(base.asExpr()) ) and trg.getField() = f and - self.getRhs() = rhs.asInstruction() + super.getRhs() = rhs.asInstruction() ) } @@ -156,13 +152,13 @@ module ControlFlow { * is the data-flow node corresponding to `base`. */ predicate writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs) { - exists(IR::ElementTarget trg | trg = self.getLhs() | + exists(IR::ElementTarget trg | trg = super.getLhs() | ( trg.getBase() = base.asInstruction() or trg.getBase() = MkImplicitDeref(base.asExpr()) ) and trg.getIndex() = index.asInstruction() and - self.getRhs() = rhs.asInstruction() + super.getRhs() = rhs.asInstruction() ) } diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 3f414c8e6af..556c5d3b726 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -124,10 +124,17 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) } /** Holds if `row` is a summary model. */ predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } +bindingset[input] +private predicate getKind(string input, string kind, boolean generated) { + input.splitAt(":", 0) = "generated" and kind = input.splitAt(":", 1) and generated = true + or + not input.matches("%:%") and kind = input and generated = false +} + /** Holds if a source model exists for the given parameters. */ predicate sourceModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string output, string kind + string output, string kind, boolean generated ) { exists(string row | sourceModel(row) and @@ -139,14 +146,14 @@ predicate sourceModel( row.splitAt(";", 4) = signature and row.splitAt(";", 5) = ext and row.splitAt(";", 6) = output and - row.splitAt(";", 7) = kind + exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated)) ) } /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string kind + string input, string kind, boolean generated ) { exists(string row | sinkModel(row) and @@ -158,22 +165,22 @@ predicate sinkModel( row.splitAt(";", 4) = signature and row.splitAt(";", 5) = ext and row.splitAt(";", 6) = input and - row.splitAt(";", 7) = kind + exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated)) ) } /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind + string input, string output, string kind, boolean generated ) { - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, _) + summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated, _) } /** Holds if a summary model `row` exists for the given parameters. */ predicate summaryModel( string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind, string row + string input, string output, string kind, boolean generated, string row ) { summaryModel(row) and row.splitAt(";", 0) = namespace and @@ -185,14 +192,14 @@ predicate summaryModel( row.splitAt(";", 5) = ext and row.splitAt(";", 6) = input and row.splitAt(";", 7) = output and - row.splitAt(";", 8) = kind + exists(string k | row.splitAt(";", 8) = k and getKind(k, kind, generated)) } /** Holds if `package` have CSV framework coverage. */ private predicate packageHasCsvCoverage(string package) { - sourceModel(package, _, _, _, _, _, _, _) or - sinkModel(package, _, _, _, _, _, _, _) or - summaryModel(package, _, _, _, _, _, _, _, _) + sourceModel(package, _, _, _, _, _, _, _, _) or + sinkModel(package, _, _, _, _, _, _, _, _) or + summaryModel(package, _, _, _, _, _, _, _, _, _) } /** @@ -234,25 +241,25 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int part = "source" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string output | + string ext, string output, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind) + sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, generated) ) or part = "sink" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input | + string ext, string input, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind) + sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, generated) ) or part = "summary" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input, string output | + string ext, string input, string output, boolean generated | canonicalPackageHasASubpackage(package, subpkg) and - summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind) + summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, generated) ) ) } @@ -261,9 +268,9 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int module CsvValidation { private string getInvalidModelInput() { exists(string pred, AccessPath input, string part | - sinkModel(_, _, _, _, _, _, input, _) and pred = "sink" + sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" or - summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary" + summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary" | ( invalidSpecComponent(input, part) and @@ -279,9 +286,9 @@ module CsvValidation { private string getInvalidModelOutput() { exists(string pred, string output, string part | - sourceModel(_, _, _, _, _, _, output, _) and pred = "source" + sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" or - summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary" + summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary" | invalidSpecComponent(output, part) and not part = "" and @@ -291,8 +298,9 @@ module CsvValidation { } private string getInvalidModelKind() { - exists(string row, string kind | summaryModel(row) | - kind = row.splitAt(";", 8) and + exists(string row, string k, string kind | summaryModel(row) | + k = row.splitAt(";", 8) and + getKind(k, kind, _) and not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) @@ -334,11 +342,11 @@ module CsvValidation { private string getInvalidModelSignature() { exists(string pred, string namespace, string type, string name, string signature, string ext | - sourceModel(namespace, type, _, name, signature, ext, _, _) and pred = "source" + sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source" or - sinkModel(namespace, type, _, name, signature, ext, _, _) and pred = "sink" + sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink" or - summaryModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "summary" + summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary" | not namespace.regexpMatch("[a-zA-Z0-9_\\./]*") and result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." @@ -371,9 +379,9 @@ pragma[nomagic] private predicate elementSpec( string namespace, string type, boolean subtypes, string name, string signature, string ext ) { - sourceModel(namespace, type, subtypes, name, signature, ext, _, _) or - sinkModel(namespace, type, subtypes, name, signature, ext, _, _) or - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or + sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or + summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) } private string paramsStringPart(Function f, int i) { @@ -421,7 +429,9 @@ SourceOrSinkElement interpretElement( predicate hasExternalSpecification(Function f) { f = any(SummarizedCallable sc).asFunction() or - exists(SourceOrSinkElement e | f = e.asEntity() | sourceElement(e, _, _) or sinkElement(e, _, _)) + exists(SourceOrSinkElement e | f = e.asEntity() | + sourceElement(e, _, _, _) or sinkElement(e, _, _, _) + ) } private predicate parseField(AccessPathToken c, DataFlow::FieldContent f) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll index ecb6f542955..0c3dc8427b2 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll @@ -1,11 +1,20 @@ /** - * Module for parsing access paths from CSV models, both the identifying access path used + * Module for parsing access paths from MaD models, both the identifying access path used * by dynamic languages, and the input/output specifications for summary steps. * * This file is used by the shared data flow library and by the JavaScript libraries * (which does not use the shared data flow libraries). */ +/** + * Convenience-predicate for extracting two capture groups at once. + */ +bindingset[input, regexp] +private predicate regexpCaptureTwo(string input, string regexp, string capture1, string capture2) { + capture1 = input.regexpCapture(regexp, 1) and + capture2 = input.regexpCapture(regexp, 2) +} + /** Companion module to the `AccessPath` class. */ module AccessPath { /** A string that should be parsed as an access path. */ @@ -13,6 +22,93 @@ module AccessPath { bindingset[this] Range() { any() } } + + /** + * Parses an integer constant `n` or interval `n1..n2` (inclusive) and gets the value + * of the constant or any value contained in the interval. + */ + bindingset[arg] + int parseInt(string arg) { + result = arg.toInt() + or + // Match "n1..n2" + exists(string lo, string hi | + regexpCaptureTwo(arg, "(-?\\d+)\\.\\.(-?\\d+)", lo, hi) and + result = [lo.toInt() .. hi.toInt()] + ) + } + + /** + * Parses a lower-bounded interval `n..` and gets the lower bound. + */ + bindingset[arg] + int parseLowerBound(string arg) { result = arg.regexpCapture("(-?\\d+)\\.\\.", 1).toInt() } + + /** + * Parses an integer constant or interval (bounded or unbounded) that explicitly + * references the arity, such as `N-1` or `N-3..N-1`. + * + * Note that expressions of form `N-x` will never resolve to a negative index, + * even if `N` is zero (it will have no result in that case). + */ + bindingset[arg, arity] + private int parseIntWithExplicitArity(string arg, int arity) { + result >= 0 and // do not allow N-1 to resolve to a negative index + exists(string lo | + // N-x + lo = arg.regexpCapture("N-(\\d+)", 1) and + result = arity - lo.toInt() + or + // N-x.. + lo = arg.regexpCapture("N-(\\d+)\\.\\.", 1) and + result = [arity - lo.toInt(), arity - 1] + ) + or + exists(string lo, string hi | + // x..N-y + regexpCaptureTwo(arg, "(-?\\d+)\\.\\.N-(\\d+)", lo, hi) and + result = [lo.toInt() .. arity - hi.toInt()] + or + // N-x..N-y + regexpCaptureTwo(arg, "N-(\\d+)\\.\\.N-(\\d+)", lo, hi) and + result = [arity - lo.toInt() .. arity - hi.toInt()] and + result >= 0 + or + // N-x..y + regexpCaptureTwo(arg, "N-(\\d+)\\.\\.(\\d+)", lo, hi) and + result = [arity - lo.toInt() .. hi.toInt()] and + result >= 0 + ) + } + + /** + * Parses an integer constant or interval (bounded or unbounded) and gets any + * of the integers contained within (of which there may be infinitely many). + * + * Has no result for arguments involving an explicit arity, such as `N-1`. + */ + bindingset[arg, result] + int parseIntUnbounded(string arg) { + result = parseInt(arg) + or + result >= parseLowerBound(arg) + } + + /** + * Parses an integer constant or interval (bounded or unbounded) that + * may reference the arity of a call, such as `N-1` or `N-3..N-1`. + * + * Note that expressions of form `N-x` will never resolve to a negative index, + * even if `N` is zero (it will have no result in that case). + */ + bindingset[arg, arity] + int parseIntWithArity(string arg, int arity) { + result = parseInt(arg) + or + result in [parseLowerBound(arg) .. arity - 1] + or + result = parseIntWithExplicitArity(arg, arity) + } } /** Gets the `n`th token on the access path as a string. */ @@ -53,7 +149,7 @@ class AccessPath extends string instanceof AccessPath::Range { * An access part token such as `Argument[1]` or `ReturnValue`, appearing in one or more access paths. */ class AccessPathToken extends string { - AccessPathToken() { this = getRawToken(any(AccessPath path), _) } + AccessPathToken() { this = getRawToken(_, _) } private string getPart(int part) { result = this.regexpCapture("([^\\[]+)(?:\\[([^\\]]*)\\])?", part) @@ -71,9 +167,16 @@ class AccessPathToken extends string { /** Gets the `n`th argument to this token, such as `x` or `y` from `Member[x,y]`. */ string getArgument(int n) { result = this.getArgumentList().splitAt(",", n).trim() } + /** Gets the `n`th argument to this `name` token, such as `x` or `y` from `Member[x,y]`. */ + pragma[nomagic] + string getArgument(string name, int n) { name = this.getName() and result = this.getArgument(n) } + /** Gets an argument to this token, such as `x` or `y` from `Member[x,y]`. */ string getAnArgument() { result = this.getArgument(_) } + /** Gets an argument to this `name` token, such as `x` or `y` from `Member[x,y]`. */ + string getAnArgument(string name) { result = this.getArgument(name, _) } + /** Gets the number of arguments to this token, such as 2 for `Member[x,y]` or zero for `ReturnValue`. */ int getNumArgument() { result = count(int n | exists(this.getArgument(n))) } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll index 019d2831e5d..8f10eee1aab 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll @@ -108,3 +108,21 @@ predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) { non * restricted to those `call`s for which a context might make a difference. */ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() } + +private int parameterPosition() { + result = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] +} + +/** A parameter position represented by an integer. */ +class ParameterPosition extends int { + ParameterPosition() { this = parameterPosition() } +} + +/** An argument position represented by an integer. */ +class ArgumentPosition extends int { + ArgumentPosition() { this = parameterPosition() } +} + +/** Holds if arguments at position `apos` match parameters at position `ppos`. */ +pragma[inline] +predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index bf150f191ed..1228d00b6ba 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -54,12 +54,23 @@ abstract class Configuration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(Node source); + predicate isSource(Node source) { none() } + + /** + * Holds if `source` is a relevant data flow source with the given initial + * `state`. + */ + predicate isSource(Node source, FlowState state) { none() } /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(Node sink); + predicate isSink(Node sink) { none() } + + /** + * Holds if `sink` is a relevant data flow sink accepting `state`. + */ + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -67,6 +78,12 @@ abstract class Configuration extends string { */ predicate isBarrier(Node node) { none() } + /** + * Holds if data flow through `node` is prohibited when the flow state is + * `state`. + */ + predicate isBarrier(Node node, FlowState state) { none() } + /** Holds if data flow into `node` is prohibited. */ predicate isBarrierIn(Node node) { none() } @@ -81,16 +98,31 @@ abstract class Configuration extends string { deprecated predicate isBarrierGuard(BarrierGuard guard) { none() } /** - * Holds if the additional flow step from `node1` to `node2` must be taken - * into account in the analysis. + * DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead. + * + * Holds if data flow through nodes guarded by `guard` is prohibited when + * the flow state is `state` + */ + deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() } + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. */ predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + none() + } + /** * Holds if an arbitrary number of implicit read steps of content `c` may be * taken at `node`. */ - predicate allowImplicitRead(Node node, Content c) { none() } + predicate allowImplicitRead(Node node, ContentSet c) { none() } /** * Gets the virtual dispatch branching limit when calculating field flow. @@ -115,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -126,12 +164,14 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -144,6 +184,14 @@ abstract class Configuration extends string { */ int explorationLimit() { none() } + /** + * Holds if hidden nodes should be included in the data flow graph. + * + * This feature should only be used for debugging or when the data flow graph + * is not visualized (for example in a `path-problem` query). + */ + predicate includeHiddenNodes() { none() } + /** * Holds if there is a partial data flow path from `source` to `node`. The * approximate distance between `node` and the closest source is `dist` and @@ -201,10 +249,16 @@ abstract private class ConfigurationRecursionPrevention extends Configuration { override predicate hasFlow(Node source, Node sink) { strictcount(Node n | this.isSource(n)) < 0 or + strictcount(Node n | this.isSource(n, _)) < 0 + or strictcount(Node n | this.isSink(n)) < 0 or + strictcount(Node n | this.isSink(n, _)) < 0 + or strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or + strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 + or super.hasFlow(source, sink) } } @@ -260,13 +314,11 @@ private class ArgNodeEx extends NodeEx { private class ParamNodeEx extends NodeEx { ParamNodeEx() { this.asNode() instanceof ParamNode } - predicate isParameterOf(DataFlowCallable c, int i) { - this.asNode().(ParamNode).isParameterOf(c, i) + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + this.asNode().(ParamNode).isParameterOf(c, pos) } - int getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } + ParameterPosition getPosition() { this.isParameterOf(_, result) } } private class RetNodeEx extends NodeEx { @@ -280,22 +332,26 @@ private class RetNodeEx extends NodeEx { private predicate inBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierIn(n) and - config.isSource(n) + config.isBarrierIn(n) + | + config.isSource(n) or config.isSource(n, _) ) } private predicate outBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierOut(n) and - config.isSink(n) + config.isBarrierOut(n) + | + config.isSink(n) or config.isSink(n, _) ) } /** A bridge class to access the deprecated `isBarrierGuard`. */ private class BarrierGuardGuardedNodeBridge extends Unit { abstract predicate guardedNode(Node n, Configuration config); + + abstract predicate guardedNode(Node n, FlowState state, Configuration config); } private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { @@ -305,6 +361,13 @@ private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { n = g.getAGuardedNode() ) } + + deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) { + exists(BarrierGuard g | + config.isBarrierGuard(g, state) and + n = g.getAGuardedNode() + ) + } } pragma[nomagic] @@ -313,23 +376,47 @@ private predicate fullBarrier(NodeEx node, Configuration config) { config.isBarrier(n) or config.isBarrierIn(n) and - not config.isSource(n) + not config.isSource(n) and + not config.isSource(n, _) or config.isBarrierOut(n) and - not config.isSink(n) + not config.isSink(n) and + not config.isSink(n, _) or any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config) ) } pragma[nomagic] -private predicate sourceNode(NodeEx node, Configuration config) { - config.isSource(node.asNode()) and - not fullBarrier(node, config) +private predicate stateBarrier(NodeEx node, FlowState state, Configuration config) { + exists(Node n | node.asNode() = n | + config.isBarrier(n, state) + or + any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config) + ) } pragma[nomagic] -private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) } +private predicate sourceNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSource(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSource(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} + +pragma[nomagic] +private predicate sinkNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSink(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSink(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} /** Provides the relevant barriers for a step from `node1` to `node2`. */ pragma[inline] @@ -366,8 +453,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - pragma[only_bind_into](config) - .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -380,6 +466,20 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat ) } +private predicate additionalLocalStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) + ) +} + /** * Holds if data can flow from `node1` to `node2` in a way that discards call contexts. */ @@ -400,21 +500,32 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - pragma[only_bind_into](config) - .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) } -private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { +private predicate additionalJumpStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - read(pragma[only_bind_into](n1), c, pragma[only_bind_into](n2)) and - stepFilter(node1, node2, config) + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) and + not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) +} + +pragma[nomagic] +private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and + stepFilter(node1, node2, config) or exists(Node n | node2.isImplicitReadNode(n, true) and @@ -423,16 +534,47 @@ private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration conf ) } +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(ContentSet cs | + readSet(node1, cs, node2, config) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate clearsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + clearsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate expectsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + expectsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +pragma[nomagic] +private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } + +pragma[nomagic] +private predicate hasReadStep(Content c, Configuration config) { read(_, c, _, config) } + +pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - exists(Node n1, Node n2 | - node1.asNode() = n1 and - node2.asNode() = n2 and - store(pragma[only_bind_into](n1), tc, pragma[only_bind_into](n2), contentType) and - read(_, tc.getContent(), _, config) and - stepFilter(node1, node2, config) - ) + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and + hasReadStep(tc.getContent(), config) and + stepFilter(node1, node2, config) } pragma[nomagic] @@ -464,14 +606,29 @@ private predicate hasSinkCallCtx(Configuration config) { ) } -private module Stage1 { - class ApApprox = Unit; +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} - class Ap = Unit; +private module Stage1 implements StageSig { + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } - class ApOption = Unit; - - class Cc = boolean; + private class Cc = boolean; /* Begin: Stage 1 logic. */ /** @@ -480,30 +637,20 @@ private module Stage1 { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { - sourceNode(node, config) and + private predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { + sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - localFlowStep(mid, node, config) + exists(NodeEx mid | fwdFlow(mid, cc, config) | + localFlowStep(mid, node, config) or + additionalLocalFlowStep(mid, node, config) or + additionalLocalStateStep(mid, _, node, _, config) ) or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - additionalLocalFlowStep(mid, node, config) - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - jumpStep(mid, node, config) and - cc = false - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - additionalJumpStep(mid, node, config) and - cc = false + exists(NodeEx mid | fwdFlow(mid, _, config) and cc = false | + jumpStep(mid, node, config) or + additionalJumpStep(mid, node, config) or + additionalJumpStateStep(mid, _, node, _, config) ) or // store @@ -514,9 +661,9 @@ private module Stage1 { ) or // read - exists(Content c | - fwdFlowRead(c, node, cc, config) and - fwdFlowConsCand(c, config) + exists(ContentSet c | + fwdFlowReadSet(c, node, cc, config) and + fwdFlowConsCandSet(c, _, config) ) or // flow into a callable @@ -540,10 +687,10 @@ private module Stage1 { private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) } pragma[nomagic] - private predicate fwdFlowRead(Content c, NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlowReadSet(ContentSet c, NodeEx node, Cc cc, Configuration config) { exists(NodeEx mid | fwdFlow(mid, cc, config) and - read(mid, c, node, config) + readSet(mid, c, node, config) ) } @@ -561,6 +708,16 @@ private module Stage1 { ) } + /** + * Holds if `cs` may be interpreted in a read as the target of some store + * into `c`, in the flow covered by `fwdFlow`. + */ + pragma[nomagic] + private predicate fwdFlowConsCandSet(ContentSet cs, Content c, Configuration config) { + fwdFlowConsCand(c, config) and + c = cs.getAReadContent() + } + pragma[nomagic] private predicate fwdFlowReturnPosition(ReturnPosition pos, Cc cc, Configuration config) { exists(RetNodeEx ret | @@ -594,6 +751,24 @@ private module Stage1 { ) } + private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1 | + additionalLocalStateStep(node1, state1, _, state2, config) or + additionalJumpStateStep(node1, state1, _, state2, config) + | + fwdFlow(node1, config) + ) + } + + private predicate fwdFlowState(FlowState state, Configuration config) { + sourceNode(_, state, config) + or + exists(FlowState state0 | + fwdFlowState(state0, config) and + stateStepFwd(state0, state, config) + ) + } + /** * Holds if `node` is part of a path from a source to a sink in the * configuration `config`. @@ -602,37 +777,30 @@ private module Stage1 { * the enclosing callable in order to reach a sink. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { + private predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { revFlow0(node, toReturn, config) and fwdFlow(node, config) } pragma[nomagic] private predicate revFlow0(NodeEx node, boolean toReturn, Configuration config) { - fwdFlow(node, config) and - sinkNode(node, config) and - if hasSinkCallCtx(config) then toReturn = true else toReturn = false - or - exists(NodeEx mid | - localFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(FlowState state | + fwdFlow(node, pragma[only_bind_into](config)) and + sinkNode(node, state, config) and + fwdFlowState(state, pragma[only_bind_into](config)) and + if hasSinkCallCtx(config) then toReturn = true else toReturn = false ) or - exists(NodeEx mid | - additionalLocalFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(NodeEx mid | revFlow(mid, toReturn, config) | + localFlowStep(node, mid, config) or + additionalLocalFlowStep(node, mid, config) or + additionalLocalStateStep(node, _, mid, _, config) ) or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false - ) - or - exists(NodeEx mid | - additionalJumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false + exists(NodeEx mid | revFlow(mid, _, config) and toReturn = false | + jumpStep(node, mid, config) or + additionalJumpStep(node, mid, config) or + additionalJumpStateStep(node, _, mid, _, config) ) or // store @@ -642,9 +810,9 @@ private module Stage1 { ) or // read - exists(NodeEx mid, Content c | - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + exists(NodeEx mid, ContentSet c | + readSet(node, c, mid, config) and + fwdFlowConsCandSet(c, _, pragma[only_bind_into](config)) and revFlow(mid, toReturn, pragma[only_bind_into](config)) ) or @@ -670,10 +838,10 @@ private module Stage1 { */ pragma[nomagic] private predicate revFlowConsCand(Content c, Configuration config) { - exists(NodeEx mid, NodeEx node | + exists(NodeEx mid, NodeEx node, ContentSet cs | fwdFlow(node, pragma[only_bind_into](config)) and - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + readSet(node, cs, mid, config) and + fwdFlowConsCandSet(cs, c, pragma[only_bind_into](config)) and revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config)) ) } @@ -692,13 +860,14 @@ private module Stage1 { * Holds if `c` is the target of both a read and a store in the flow covered * by `revFlow`. */ - private predicate revFlowIsReadAndStored(Content c, Configuration conf) { + pragma[nomagic] + additional predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } pragma[nomagic] - predicate viableReturnPosOutNodeCandFwd1( + additional predicate viableReturnPosOutNodeCandFwd1( DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config ) { fwdFlowReturnPosition(pos, _, config) and @@ -714,7 +883,7 @@ private module Stage1 { } pragma[nomagic] - predicate viableParamArgNodeCandFwd1( + additional predicate viableParamArgNodeCandFwd1( DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config ) { viableParamArgEx(call, p, arg) and @@ -749,6 +918,31 @@ private module Stage1 { ) } + private predicate stateStepRev(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1, NodeEx node2 | + additionalLocalStateStep(node1, state1, node2, state2, config) or + additionalJumpStateStep(node1, state1, node2, state2, config) + | + revFlow(node1, _, pragma[only_bind_into](config)) and + revFlow(node2, _, pragma[only_bind_into](config)) and + fwdFlowState(state1, pragma[only_bind_into](config)) and + fwdFlowState(state2, pragma[only_bind_into](config)) + ) + } + + additional predicate revFlowState(FlowState state, Configuration config) { + exists(NodeEx node | + sinkNode(node, state, config) and + revFlow(node, _, pragma[only_bind_into](config)) and + fwdFlowState(state, pragma[only_bind_into](config)) + ) + or + exists(FlowState state0 | + revFlowState(state0, config) and + stateStepRev(state, state0, config) + ) + } + pragma[nomagic] predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -766,15 +960,24 @@ private module Stage1 { pragma[nomagic] predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config) { revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and - revFlow(n2, pragma[only_bind_into](config)) and - read(n1, c, n2, pragma[only_bind_into](config)) + read(n1, c, n2, pragma[only_bind_into](config)) and + revFlow(n2, pragma[only_bind_into](config)) } pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow(node, toReturn, config) and exists(returnAp) and exists(ap) + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, _, pragma[only_bind_into](config)) and + exists(state) and + exists(ap) } private predicate throughFlowNodeCand(NodeEx node, Configuration config) { @@ -801,21 +1004,26 @@ private module Stage1 { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -825,17 +1033,21 @@ private module Stage1 { ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + additional predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and nodes = count(NodeEx node | fwdFlow(node, config)) and fields = count(Content f0 | fwdFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | fwdFlowState(state, config)) and tuples = count(NodeEx n, boolean b | fwdFlow(n, b, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, config)) and fields = count(Content f0 | revFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | revFlowState(state, config)) and tuples = count(NodeEx n, boolean b | revFlow(n, b, config)) } /* End: Stage 1 logic. */ @@ -868,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -903,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -915,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -931,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -952,575 +1171,979 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false ) } -private module Stage2 { - module PrevStage = Stage1; +private signature module StageSig { + class Ap; + predicate revFlow(NodeEx node, Configuration config); + + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); + + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); + + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); + + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ); + + predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config); +} + +private module MkStage { class ApApprox = PrevStage::Ap; - class Ap = boolean; + signature module StageParam { + class Ap; - class ApNil extends Ap { - ApNil() { this = false } + class ApNil extends Ap; + + bindingset[result, ap] + ApApprox getApprox(Ap ap); + + ApNil getApNil(NodeEx node); + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail); + + Content getHeadContent(Ap ap); + + class ApOption; + + ApOption apNone(); + + ApOption apSome(Ap ap); + + class Cc; + + class CcCall extends Cc; + + // TODO: member predicate on CcCall + predicate matchesCall(CcCall cc, DataFlowCall call); + + class CcNoCall extends Cc; + + Cc ccNone(); + + CcCall ccSomeCall(); + + class LocalCc; + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc); + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc); + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc); + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ); + + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config + ); + + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ); + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config); + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType); } - bindingset[result, ap] - private ApApprox getApprox(Ap ap) { any() } + module Stage implements StageSig { + import Param - private ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and exists(result) } + /* Begin: Stage logic. */ + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } - bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } - pragma[inline] - private Content getHeadContent(Ap ap) { exists(result) and ap = true } + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } - class ApOption = BooleanOption; + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, + ApApprox argApa, ApApprox apa, Configuration config + ) { + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) + } - ApOption apNone() { result = TBooleanNone() } + /** + * Holds if `node` is reachable with access path `ap` from a source in the + * configuration `config`. + * + * The call context `cc` records whether the node is reached through an + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. + */ + pragma[nomagic] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config + ) { + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and + filter(node, state, ap, config) + } - ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config + ) { + sourceNode(node, state, config) and + (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and + argAp = apNone() and + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) + or + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and + localCc = getLocalCc(mid, cc) + | + localStep(mid, state0, node, state, true, _, config, localCc) and + ap = ap0 and + apa = apa0 + or + localStep(mid, state0, node, state, false, ap, config, localCc) and + ap0 instanceof ApNil and + apa = getApprox(ap) + ) + or + exists(NodeEx mid | + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and + jumpStep(mid, node, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStep(mid, node, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() and + ap = getApNil(node) and + apa = getApprox(ap) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() and + ap = getApNil(node) and + apa = getApprox(ap) + ) + or + // store + exists(TypedContent tc, Ap ap0 | + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) + ) + or + // read + exists(Ap ap0, Content c | + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) + ) + or + // flow into a callable + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) + or + // flow out of a callable + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + or + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowStore( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and + typecheckStore(ap1, contentType) + ) + } + + /** + * Holds if forward flow with access path `tail` reaches a store of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(TypedContent tc | + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and + tc.getContent() = c and + cons = apCons(tc, tail) + ) + } + + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + + pragma[nomagic] + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, + Configuration config + ) { + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, c, node2, config) and + getHeadContent(ap) = c + } + + pragma[nomagic] + private predicate fwdFlowIn( + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config + ) { + exists(ArgNodeEx arg, boolean allowsFieldFlow | + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config + ) { + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) + ) + } + + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) + } + + /** + * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` + * and data might flow through the target callable and back out at `call`. + */ + pragma[nomagic] + private predicate fwdFlowIsEntered( + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config + ) { + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate storeStepFwd( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config + ) { + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and + ap2 = apCons(tc, ap1) and + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) + } + + private predicate readStepFwd( + NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config + ) { + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and + fwdFlowConsCand(ap1, c, ap2, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config + ) { + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config + ) { + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) + } + + /** + * Holds if `node` with access path `ap` is part of a path from a source to a + * sink in the configuration `config`. + * + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. + */ + pragma[nomagic] + additional predicate revFlow( + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config + ) { + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) + } + + pragma[nomagic] + private predicate revFlow0( + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, _, _, _, ap, config) and + sinkNode(node, state, config) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and + returnAp = apNone() and + ap instanceof ApNil + or + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, returnCtx, returnAp, ap, config) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and + ap instanceof ApNil + ) + or + exists(NodeEx mid | + jumpStep(node, mid, config) and + revFlow(mid, state, _, _, ap, config) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStep(node, mid, config) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() and + ap instanceof ApNil + ) + or + // store + exists(Ap ap0, Content c | + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and + revFlowConsCand(ap0, c, ap, config) + ) + or + // read + exists(NodeEx mid, Ap ap0 | + revFlow(mid, state, returnCtx, returnAp, ap0, config) and + readStepFwd(node, ap, _, mid, ap0, config) + ) + or + // flow into a callable + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) + or + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) + ) + or + // flow out of a callable + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) + } + + pragma[nomagic] + private predicate revFlowStore( + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + ReturnCtx returnCtx, ApOption returnAp, Configuration config + ) { + revFlow(mid, state, returnCtx, returnAp, ap0, config) and + storeStepFwd(node, ap, tc, mid, ap0, config) and + tc.getContent() = c + } + + /** + * Holds if reverse flow with access path `tail` reaches a read of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(NodeEx mid, Ap tail0 | + revFlow(mid, _, _, _, tail, config) and + tail = pragma[only_bind_into](tail0) and + readStepFwd(_, cons, c, mid, tail0, config) + ) + } + + pragma[nomagic] + private predicate revFlowOut( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config + ) { + exists(NodeEx out, boolean allowsFieldFlow | + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config + ) { + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) + } + + pragma[nomagic] + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config + ) { + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) + } + + /** + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. + */ + pragma[nomagic] + private predicate revFlowIsReturned( + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config + ) { + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + matchesCall(ccc, call) + ) + } + + pragma[nomagic] + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ) { + exists(Ap ap2, Content c | + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and + revFlowConsCand(ap2, c, ap1, config) + ) + } + + predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(Ap ap1, Ap ap2 | + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + readStepFwd(node1, ap1, c, node2, ap2, config) and + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, + pragma[only_bind_into](config)) + ) + } + + additional predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + additional predicate revFlowAlias(NodeEx node, Configuration config) { + revFlow(node, _, _, _, _, config) + } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, ap, config) + } + + private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepFwd(_, ap, tc, _, _, config) + } + + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepCand(_, ap, tc, _, _, config) + } + + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + additional predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config + ) { + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) + } + + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) + ) + } + + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) + ) + } + + additional predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { + fwd = true and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and + fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) + ) + or + fwd = false and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | consCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) + ) + } + /* End: Stage logic. */ + } +} + +private module BooleanCallContext { + class Cc extends boolean { + Cc() { this in [true, false] } + } + + class CcCall extends Cc { + CcCall() { this = true } + } + + /** Holds if the call context may be `call`. */ + predicate matchesCall(CcCall cc, DataFlowCall call) { any() } + + class CcNoCall extends Cc { + CcNoCall() { this = false } + } + + Cc ccNone() { result = false } + + CcCall ccSomeCall() { result = true } + + class LocalCc = Unit; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } +} + +private module Level1CallContext { class Cc = CallContext; class CcCall = CallContextCall; + pragma[inline] + predicate matchesCall(CcCall cc, DataFlowCall call) { cc.matchesCall(call) } + class CcNoCall = CallContextNoCall; Cc ccNone() { result instanceof CallContextAny } CcCall ccSomeCall() { result instanceof CallContextSomeCall } - private class LocalCc = Unit; + module NoLocalCallContext { + class LocalCc = Unit; - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSiteDispatch(call, c) - then result = TSpecificCall(call) - else result = TSomeCall() + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } + } + + module LocalCallContext { + class LocalCc = LocalCallContext; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { + result = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + node.getEnclosingCallable()) + } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() + } } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { checkCallContextReturn(innercc, c, call) and if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } +} - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } +private module Stage2Param implements MkStage::StageParam { + private module PrevStage = Stage1; - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + class Ap extends boolean { + Ap() { this in [true, false] } + } + + class ApNil extends Ap { + ApNil() { this = false } + } + + bindingset[result, ap] + PrevStage::Ap getApprox(Ap ap) { any() } + + ApNil getApNil(NodeEx node) { Stage1::revFlow(node, _) and exists(result) } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + + pragma[inline] + Content getHeadContent(Ap ap) { exists(result) and ap = true } + + class ApOption = BooleanOption; + + ApOption apNone() { result = TBooleanNone() } + + ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + + import Level1CallContext + import NoLocalCallContext + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { ( preservesValue = true and - localFlowStepNodeCand1(node1, node2, config) + localFlowStepNodeCand1(node1, node2, config) and + state1 = state2 or preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, config) + additionalLocalFlowStepNodeCand1(node1, node2, config) and + state1 = state2 + or + preservesValue = false and + additionalLocalStateStep(node1, state1, node2, state2, config) ) and exists(ap) and exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; - private predicate flowIntoCall = flowIntoCallNodeCand1/5; + predicate flowIntoCall = flowIntoCallNodeCand1/5; - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and + expectsContentEx(node, c) + ) + } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + PrevStage::revFlowState(state, pragma[only_bind_into](config)) and + exists(ap) and + not stateBarrier(node, state, config) and + ( + notExpectsContent(node) + or + ap = true and + expectsContentCand(node, config) + ) + } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } +} - /* Begin: Stage 2 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 2 logic. */ +private module Stage2 implements StageSig { + import MkStage::Stage } pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } pragma[nomagic] @@ -1530,7 +2153,7 @@ private predicate flowIntoCallNodeCand2( ) { flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } private module LocalFlowBigStep { @@ -1541,7 +2164,8 @@ private module LocalFlowBigStep { private class FlowCheckNode extends NodeEx { FlowCheckNode() { castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) + clearsContentCached(this.asNode(), _) or + expectsContentCached(this.asNode(), _) } } @@ -1549,17 +2173,31 @@ private module LocalFlowBigStep { * Holds if `node` can be the first node in a maximal subsequence of local * flow steps in a dataflow path. */ - predicate localFlowEntry(NodeEx node, Configuration config) { - Stage2::revFlow(node, config) and + private predicate localFlowEntry(NodeEx node, FlowState state, Configuration config) { + Stage2::revFlow(node, state, config) and ( - sourceNode(node, config) or - jumpStep(_, node, config) or - additionalJumpStep(_, node, config) or - node instanceof ParamNodeEx or - node.asNode() instanceof OutNodeExt or - store(_, _, node, _, config) or - read(_, _, node, config) or + sourceNode(node, state, config) + or + jumpStep(_, node, config) + or + additionalJumpStep(_, node, config) + or + additionalJumpStateStep(_, _, node, state, config) + or + node instanceof ParamNodeEx + or + node.asNode() instanceof OutNodeExt + or + Stage2::storeStepCand(_, _, _, node, _, config) + or + Stage2::readStepCand(_, _, node, config) + or node instanceof FlowCheckNode + or + exists(FlowState s | + additionalLocalStateStep(_, s, node, state, config) and + s != state + ) ) } @@ -1567,28 +2205,42 @@ private module LocalFlowBigStep { * Holds if `node` can be the last node in a maximal subsequence of local * flow steps in a dataflow path. */ - private predicate localFlowExit(NodeEx node, Configuration config) { - exists(NodeEx next | Stage2::revFlow(next, config) | + private predicate localFlowExit(NodeEx node, FlowState state, Configuration config) { + exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or - store(node, _, next, _, config) or - read(node, _, next, config) + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or + Stage2::storeStepCand(node, _, _, next, _, config) or + Stage2::readStepCand(node, _, next, config) ) or + exists(NodeEx next, FlowState s | Stage2::revFlow(next, s, config) | + additionalJumpStateStep(node, state, next, s, config) + or + additionalLocalStateStep(node, state, next, s, config) and + s != state + ) + or + Stage2::revFlow(node, state, config) and node instanceof FlowCheckNode or - sinkNode(node, config) + sinkNode(node, state, config) } pragma[noinline] private predicate additionalLocalFlowStepNodeCand2( - NodeEx node1, NodeEx node2, Configuration config + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, Configuration config ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and - Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config)) + state1 = state2 and + Stage2::revFlow(node1, pragma[only_bind_into](state1), false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false, + pragma[only_bind_into](config)) + or + additionalLocalStateStep(node1, state1, node2, state2, config) and + Stage2::revFlow(node1, state1, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, false, pragma[only_bind_into](config)) } /** @@ -1600,40 +2252,40 @@ private module LocalFlowBigStep { */ pragma[nomagic] private predicate localFlowStepPlus( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, Configuration config, - LocalCallContext cc + NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, + Configuration config, LocalCallContext cc ) { not isUnreachableInCallCached(node2.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and ( - localFlowEntry(node1, pragma[only_bind_into](config)) and + localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](config)) and ( localFlowStepNodeCand1(node1, node2, config) and preservesValue = true and - t = node1.getDataFlowType() // irrelevant dummy value + t = node1.getDataFlowType() and // irrelevant dummy value + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) or - additionalLocalFlowStepNodeCand2(node1, node2, config) and + additionalLocalFlowStepNodeCand2(node1, state, node2, state, config) and preservesValue = false and t = node2.getDataFlowType() ) and node1 != node2 and cc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and + localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue, t, + pragma[only_bind_into](config), cc) and localFlowStepNodeCand1(mid, node2, config) and not mid instanceof FlowCheckNode and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) ) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and - additionalLocalFlowStepNodeCand2(mid, node2, config) and + localFlowStepPlus(node1, state, mid, _, _, pragma[only_bind_into](config), cc) and + additionalLocalFlowStepNodeCand2(mid, state, node2, state, config) and not mid instanceof FlowCheckNode and preservesValue = false and - t = node2.getDataFlowType() and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + t = node2.getDataFlowType() ) ) } @@ -1644,36 +2296,121 @@ private module LocalFlowBigStep { */ pragma[nomagic] predicate localFlowBigStep( - NodeEx node1, NodeEx node2, boolean preservesValue, AccessPathFrontNil apf, - Configuration config, LocalCallContext callContext + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, node2, preservesValue, apf.getType(), config, callContext) and - localFlowExit(node2, config) + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and + localFlowExit(node2, state1, config) and + state1 = state2 + or + additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and + state1 != state2 and + preservesValue = false and + t = node2.getDataFlowType() and + callContext.relevantFor(node1.getEnclosingCallable()) and + not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | + isUnreachableInCallCached(node1.asNode(), call) or + isUnreachableInCallCached(node2.asNode(), call) + ) } } private import LocalFlowBigStep -private module Stage3 { - module PrevStage = Stage2; +private module Stage3Param implements MkStage::StageParam { + private module PrevStage = Stage2; - class ApApprox = PrevStage::Ap; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } + Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathFrontOption; @@ -1681,542 +2418,114 @@ private module Stage3 { ApOption apSome(Ap ap) { result = TAccessPathFrontSome(ap) } - class Cc = boolean; - - class CcCall extends Cc { - CcCall() { this = true } - - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } - - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } - - CcCall ccSomeCall() { result = true } - - private class LocalCc = Unit; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } - - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc - ) { - localFlowBigStep(node1, node2, preservesValue, ap, config, _) and exists(lcc) - } - - private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; - - private predicate flowIntoCall = flowIntoCallNodeCand2/5; + import BooleanCallContext pragma[nomagic] - private predicate clear(NodeEx node, Ap ap) { ap.isClearedAt(node.asNode()) } + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) + } + + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { + PrevStage::revFlow(node, config) and + clearsContentCached(node.asNode(), c) + } + + pragma[nomagic] + private predicate clearContent(NodeEx node, Content c, Configuration config) { + exists(ContentSet cs | + PrevStage::readStepCand(_, pragma[only_bind_into](c), _, pragma[only_bind_into](config)) and + c = cs.getAReadContent() and + clearSet(node, cs, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clear(NodeEx node, Ap ap, Configuration config) { + clearContent(node, ap.getHead().getContent(), config) + } + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getHead().getContent() + ) + } pragma[nomagic] private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { - not clear(node, ap) and - if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + not clear(node, ap, config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { + predicate typecheckStore(Ap ap, DataFlowType contentType) { // We need to typecheck stores here, since reverse flow through a getter // might have a different type here compared to inside the getter. compatibleTypes(ap.getType(), contentType) } +} - /* Begin: Stage 3 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 3 logic. */ +private module Stage4 implements StageSig { + import MkStage::Stage } /** * Holds if `argApf` is recorded as the summary context for flow reaching `node` * and remains relevant for the following pruning stage. */ -private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { +private predicate flowCandSummaryCtx( + NodeEx node, FlowState state, AccessPathFront argApf, Configuration config +) { exists(AccessPathFront apf | - Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2226,12 +2535,12 @@ private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Config */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = - strictcount(NodeEx n | - Stage3::revFlow(n, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + strictcount(NodeEx n, FlowState state | + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or - flowCandSummaryCtx(n, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and @@ -2243,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2377,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2388,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2413,26 +2722,25 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4 { - module PrevStage = Stage3; - - class ApApprox = PrevStage::Ap; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; - private ApApprox getApprox(Ap ap) { result = ap.getFront() } + pragma[nomagic] + PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } + Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathApproxOption; @@ -2440,559 +2748,88 @@ private module Stage4 { ApOption apSome(Ap ap) { result = TAccessPathApproxSome(ap) } - class Cc = CallContext; + import Level1CallContext + import LocalCallContext - class CcCall = CallContextCall; - - class CcNoCall = CallContextNoCall; - - Cc ccNone() { result instanceof CallContextAny } - - CcCall ccSomeCall() { result instanceof CallContextSomeCall } - - private class LocalCc = LocalCallContext; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() - } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { - checkCallContextReturn(innercc, c, call) and - if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() - } - - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { - localFlowEntry(node, config) and - result = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - node.getEnclosingCallable()) - } - - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) } pragma[nomagic] - private predicate flowIntoCall( + predicate flowIntoCall( DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } - - /* Begin: Stage 4 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 4 logic. */ + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } +private module Stage5 = MkStage::Stage; + bindingset[conf, result] private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) } -private predicate nodeMayUseSummary(NodeEx n, AccessPathApprox apa, Configuration config) { - exists(DataFlowCallable c, AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, apa, _) and - Stage4::revFlow(n, true, _, apa0, config) and - Stage4::fwdFlow(n, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c +pragma[nomagic] +private predicate nodeMayUseSummary0( + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(AccessPathApprox apa0 | + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) + ) +} + +pragma[nomagic] +private predicate nodeMayUseSummary( + NodeEx n, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } private newtype TSummaryCtx = TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, AccessPath ap) { - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _) + TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { + exists(Configuration config | + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) + ) } /** @@ -3013,11 +2850,12 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { /** A summary context from which a flow summary can be generated. */ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { private ParamNodeEx p; + private FlowState s; private AccessPath ap; - SummaryCtxSome() { this = TSummaryCtxSome(p, ap) } + SummaryCtxSome() { this = TSummaryCtxSome(p, s, ap) } - int getParameterPos() { p.isParameterOf(_, result) } + ParameterPosition getParameterPos() { p.isParameterOf(_, result) } ParamNodeEx getParamNode() { result = p } @@ -3039,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -3047,8 +2885,8 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = - strictcount(NodeEx n | - Stage4::revFlow(n, _, _, apa, config) or nodeMayUseSummary(n, apa, config) + strictcount(NodeEx n, FlowState state | + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3069,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -3092,6 +2930,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 @@ -3110,6 +2949,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 @@ -3144,10 +2984,13 @@ private newtype TAccessPath = } private newtype TPathNode = - TPathNodeMid(NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) { + pragma[assume_small_delta] + TPathNodeMid( + NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config + ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, config) and - sourceNode(node, config) and + Stage5::revFlow(node, state, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3158,15 +3001,28 @@ private newtype TPathNode = or // ... or a step from an existing PathNode to another node. exists(PathNodeMid mid | - pathStep(mid, node, cc, sc, ap) and + pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or - TPathNodeSink(NodeEx node, Configuration config) { + TPathNodeSink(NodeEx node, FlowState state, Configuration config) { exists(PathNodeMid sink | sink.isAtSink() and node = sink.getNodeEx() and + state = sink.getState() and + config = sink.getConfiguration() + ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and config = sink.getConfiguration() ) } @@ -3177,7 +3033,7 @@ private newtype TPathNode = * of dereference operations needed to get from the value in the node to the * tracked object. The final type indicates the type of the tracked object. */ -abstract private class AccessPath extends TAccessPath { +private class AccessPath extends TAccessPath { /** Gets the head of this access path, if any. */ abstract TypedContent getHead(); @@ -3238,6 +3094,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 @@ -3246,6 +3103,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) { @@ -3287,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -3318,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -3334,66 +3192,61 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { } } -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source are generated. - */ -class PathNode extends TPathNode { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - string toStringWithContext() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() - } - - /** Gets the underlying `Node`. */ - final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } +abstract private class PathNodeImpl extends TPathNode { + /** Gets the `FlowState` of this node. */ + abstract FlowState getState(); /** Gets the associated configuration. */ - Configuration getConfiguration() { none() } - - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() - } + abstract Configuration getConfiguration(); /** Holds if this node is a source. */ - predicate isSource() { none() } -} + abstract predicate isSource(); -abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + pragma[nomagic] + private PathNodeImpl getANonHiddenSuccessor0() { + result = this.getASuccessorIfHidden*() and + not result.isHidden() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getANonHiddenSuccessor0() and + not this.isHidden() + } abstract NodeEx getNodeEx(); predicate isHidden() { - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink + not this.getConfiguration().includeHiddenNodes() and + ( + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + ) + } + + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) or - this.getNodeEx() instanceof TNodeImplicitRead + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup } private string ppAp() { @@ -3410,13 +3263,23 @@ abstract private class PathNodeImpl extends PathNode { result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" } - override string toString() { result = this.getNodeEx().toString() + this.ppAp() } + /** Gets a textual representation of this element. */ + string toString() { result = this.getNodeEx().toString() + this.ppAp() } - override string toStringWithContext() { - result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() - } + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() } - override predicate hasLocationInfo( + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) @@ -3424,31 +3287,93 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } -/** Holds if `n` can reach a sink or is used in a subpath. */ -private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } +/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ +private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} -private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) +private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + +/** + * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. + * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. + */ +class PathNode instanceof PathNodeImpl { + PathNode() { reach(this) } + + /** Gets a textual representation of this element. */ + final string toString() { result = super.toString() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + final string toStringWithContext() { result = super.toStringWithContext() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + final predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** Gets the underlying `Node`. */ + final Node getNode() { super.getNodeEx().projectToNode() = result } + + /** Gets the `FlowState` of this node. */ + final FlowState getState() { result = super.getState() } + + /** Gets the associated configuration. */ + final Configuration getConfiguration() { result = super.getConfiguration() } + + /** Gets a successor of this node, if any. */ + final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() } + + /** Holds if this node is a source. */ + final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } +} /** * Provides the query predicates needed to include a graph in a path-problem query. */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { - reach(n) and key = "semmle.label" and val = n.toString() + key = "semmle.label" and val = n.toString() } - query predicate subpaths = Subpaths::subpaths/4; + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + Subpaths::subpaths(arg, par, ret, out) + } } /** @@ -3457,15 +3382,18 @@ module PathGraph { */ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { NodeEx node; + FlowState state; CallContext cc; SummaryCtx sc; AccessPath ap; Configuration config; - PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) } + PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, ap, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } SummaryCtx getSummaryCtx() { result = sc } @@ -3475,8 +3403,8 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { override Configuration getConfiguration() { result = config } private PathNodeMid getSuccMid() { - pathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx(), - result.getAp()) and + pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx(), result.getAp()) and result.getConfiguration() = unbindConf(this.getConfiguration()) } @@ -3489,18 +3417,18 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } override predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall else cc instanceof CallContextAny ) and sc instanceof SummaryCtxNone and - ap instanceof AccessPathNil + ap = TAccessPathNil(node.getDataFlowType()) } predicate isAtSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and ap instanceof AccessPathNil and if hasSinkCallCtx(config) then @@ -3522,6 +3450,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { PathNodeSink projectToSink() { this.isAtSink() and result.getNodeEx() = node and + result.getState() = state and result.getConfiguration() = unbindConf(config) } } @@ -3533,91 +3462,176 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { */ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { NodeEx node; + FlowState state; Configuration config; - PathNodeSink() { this = TPathNodeSink(node, config) } + PathNodeSink() { this = TPathNodeSink(node, state, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } - override predicate isSource() { sourceNode(node, config) } + override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private predicate pathNode( + PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, + Configuration conf, LocalCallContext localCC +) { + midnode = mid.getNodeEx() and + state = mid.getState() and + conf = mid.getConfiguration() and + cc = mid.getCallContext() and + sc = mid.getSummaryCtx() and + localCC = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + midnode.getEnclosingCallable()) and + ap = mid.getAp() } /** * 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, CallContext cc, SummaryCtx sc, AccessPath ap + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap ) { - exists(AccessPath ap0, NodeEx midnode, Configuration conf, LocalCallContext localCC | - midnode = mid.getNodeEx() and - conf = mid.getConfiguration() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - localCC = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - midnode.getEnclosingCallable()) and - ap0 = mid.getAp() + exists(NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | + pathNode(mid, midnode, state0, cc, sc, ap, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, true, _, conf, localCC) + ) + or + exists( + AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | - localFlowBigStep(midnode, node, true, _, conf, localCC) and - ap = ap0 - or - localFlowBigStep(midnode, node, false, ap.getFront(), conf, localCC) and + pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or jumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and ap = mid.getAp() or additionalJumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and mid.getAp() instanceof AccessPathNil and ap = TAccessPathNil(node.getDataFlowType()) or - exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, mid.getConfiguration()) and + cc instanceof CallContextAny and + sc instanceof SummaryCtxNone and + mid.getAp() instanceof AccessPathNil and + ap = TAccessPathNil(node.getDataFlowType()) + or + exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, cc)) and sc = mid.getSummaryCtx() or - exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and + exists(TypedContent tc | pathReadStep(mid, node, state, ap.push(tc), tc, cc)) and sc = mid.getSummaryCtx() or - pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp() + pathIntoCallable(mid, node, state, _, cc, sc, _, _) and ap = mid.getAp() or - pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone + pathOutOfCallable(mid, node, state, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone or - pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx() + pathThroughCallable(mid, node, state, cc, ap) and sc = mid.getSummaryCtx() } pragma[nomagic] private predicate pathReadStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } pragma[nomagic] private predicate pathStoreStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } private predicate pathOutOfCallable0( - PathNodeMid mid, ReturnPosition pos, CallContext innercc, AccessPathApprox apa, + PathNodeMid mid, ReturnPosition pos, FlowState state, CallContext innercc, AccessPathApprox apa, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and apa = mid.getAp().getApprox() and @@ -3626,11 +3640,11 @@ private predicate pathOutOfCallable0( pragma[nomagic] private predicate pathOutOfCallable1( - PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, AccessPathApprox apa, - Configuration config + PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPathApprox apa, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - pathOutOfCallable0(mid, pos, innercc, apa, config) and + pathOutOfCallable0(mid, pos, state, innercc, apa, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -3644,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3652,9 +3666,9 @@ private NodeEx getAnOutNodeFlow( * is a return from a callable and is recorded by `cc`, if needed. */ pragma[noinline] -private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) { +private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, FlowState state, CallContext cc) { exists(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config | - pathOutOfCallable1(mid, call, kind, cc, apa, config) and + pathOutOfCallable1(mid, call, kind, state, cc, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3664,39 +3678,37 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) */ pragma[noinline] private predicate pathIntoArg( - PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa, - Configuration config + PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call, + AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(ArgNode arg | - arg = mid.getNodeEx().asNode() and - cc = mid.getCallContext() and - arg.argumentOf(call, i) and - ap = mid.getAp() and + exists(ArgNodeEx arg, ArgumentPosition apos | + pathNode(mid, arg, state, cc, _, ap, config, _) and + arg.asNode().(ArgNode).argumentOf(call, apos) and apa = ap.getApprox() and - config = mid.getConfiguration() + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate parameterCand( - DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config + DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, apa, config) and - p.isParameterOf(callable, i) + Stage5::revFlow(p, _, apa, config) and + p.isParameterOf(callable, pos) ) } pragma[nomagic] private predicate pathIntoCallable0( - PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call, - AccessPath ap, Configuration config + PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, AccessPath ap, Configuration config ) { exists(AccessPathApprox apa | - pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa), - pragma[only_bind_into](config)) and + pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and callable = resolveCall(call, outercc) and - parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa), + parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa), pragma[only_bind_into](config)) ) } @@ -3708,16 +3720,16 @@ private predicate pathIntoCallable0( */ pragma[nomagic] private predicate pathIntoCallable( - PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc, - DataFlowCall call, Configuration config + PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, + SummaryCtx sc, DataFlowCall call, Configuration config ) { - exists(int i, DataFlowCallable callable, AccessPath ap | - pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap | + pathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and ( - sc = TSummaryCtxSome(p, ap) + sc = TSummaryCtxSome(p, state, ap) or - not exists(TSummaryCtxSome(p, ap)) and + not exists(TSummaryCtxSome(p, state, ap)) and sc = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also @@ -3734,35 +3746,25 @@ private predicate pathIntoCallable( /** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */ pragma[nomagic] private predicate paramFlowsThrough( - ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, - Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, + AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, int pos | - mid.getNodeEx() = ret and + exists(PathNodeMid mid, RetNodeEx ret | + pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - config = mid.getConfiguration() and - ap = mid.getAp() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } pragma[nomagic] private predicate pathThroughCallable0( - DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap, - AccessPathApprox apa, Configuration config + DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPath ap, AccessPathApprox apa, Configuration config ) { exists(CallContext innercc, SummaryCtx sc | - pathIntoCallable(mid, _, cc, innercc, sc, call, config) and - paramFlowsThrough(kind, innercc, sc, ap, apa, config) + pathIntoCallable(mid, _, _, cc, innercc, sc, call, config) and + paramFlowsThrough(kind, state, innercc, sc, ap, apa, config) ) } @@ -3771,9 +3773,11 @@ private predicate pathThroughCallable0( * The context `cc` is restored to its value prior to entering the callable. */ pragma[noinline] -private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) { +private predicate pathThroughCallable( + PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, AccessPath ap +) { exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config | - pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and + pathThroughCallable0(call, mid, kind, state, cc, ap, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3786,47 +3790,44 @@ private module Subpaths { pragma[nomagic] private predicate subpaths01( PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { exists(Configuration config | - pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and - pathIntoCallable(arg, par, _, innercc, sc, _, config) and - paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and + pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, _, innercc, sc, _, config) and + paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc, + pragma[only_bind_into](apout), _, unbindConf(config)) and not arg.isHidden() ) } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `apout`, and `innercc`. + * `kind`, `sc`, `sout`, `apout`, and `innercc`. */ pragma[nomagic] private predicate subpaths02( - PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, FlowState sout, AccessPath apout ) { - subpaths01(arg, par, sc, innercc, kind, out, apout) and + subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and out.asNode() = kind.getAnOutNode(_) } pragma[nomagic] - private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple. */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | - subpaths02(arg, par, sc, innercc, kind, out, apout) and - ret.getNodeEx() = retnode and - kind = retnode.getKind() and - innercc = ret.getCallContext() and - sc = ret.getSummaryCtx() and - ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and - apout = ret.getAp() + subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and + pathNode(ret, retnode, sout, innercc, sc, apout, unbindConf(getPathNodeConf(arg)), _) and + kind = retnode.getKind() ) } @@ -3834,38 +3835,44 @@ private module Subpaths { n.getASuccessorImpl() = result and result.isHidden() and exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() | - localFlowBigStep(n1, n2, _, _, _, _) or + localFlowBigStep(n1, _, n2, _, _, _, _, _) or store(n1, _, n2, _, _) or - read(n1, _, n2, _) + readSet(n1, _, n2, _) ) } + pragma[nomagic] + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and + succNode = succ.getNodeEx() + } + /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) { - exists(ParamNodeEx p, NodeEx o, AccessPath apout | - pragma[only_bind_into](arg).getASuccessor() = par and - pragma[only_bind_into](arg).getASuccessor() = out and - subpaths03(arg, p, localStepToHidden*(ret), o, apout) and + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) { + exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and + subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and + hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and - par.getNodeEx() = p and - out.getNodeEx() = o and - out.getAp() = apout + pathNode(out0, o, sout, _, _, apout, _, _) + | + out = out0 or out = out0.projectToSink() ) } /** - * Holds if `n` can reach a return node in a summarized subpath. + * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { - subpaths(_, _, n, _) + predicate retReach(PathNodeImpl n) { + exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } @@ -3877,12 +3884,22 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( - PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration + PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, + Configuration configuration ) { flowsource.isSource() and flowsource.getConfiguration() = configuration and - flowsource.(PathNodeImpl).getNodeEx().asNode() = source and + flowsource.getNodeEx().asNode() = source and (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and flowsink.getNodeEx().asNode() = sink } @@ -3897,18 +3914,22 @@ predicate flowsTo(Node source, Node sink, Configuration configuration) { flowsTo(_, _, source, sink, configuration) } -private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, int tuples) { +private predicate finalStats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples +) { fwd = true and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0)) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and - tuples = count(PathNode pn) + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and + tuples = count(PathNodeImpl pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and - tuples = count(PathNode pn | reach(pn)) + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and + tuples = count(PathNode pn) } /** @@ -3917,27 +3938,52 @@ private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, i * Calculates per-stage metrics for data flow. */ predicate stageStats( - int n, string stage, int nodes, int fields, int conscand, int tuples, Configuration config + int n, string stage, int nodes, int fields, int conscand, int states, int tuples, + Configuration config ) { - stage = "1 Fwd" and n = 10 and Stage1::stats(true, nodes, fields, conscand, tuples, config) + stage = "1 Fwd" and + n = 10 and + Stage1::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "1 Rev" and n = 15 and Stage1::stats(false, nodes, fields, conscand, tuples, config) + stage = "1 Rev" and + n = 15 and + Stage1::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "2 Fwd" and n = 20 and Stage2::stats(true, nodes, fields, conscand, tuples, config) + stage = "2 Fwd" and + n = 20 and + Stage2::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "2 Rev" and n = 25 and Stage2::stats(false, nodes, fields, conscand, tuples, config) + stage = "2 Rev" and + n = 25 and + Stage2::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "3 Fwd" and n = 30 and Stage3::stats(true, nodes, fields, conscand, tuples, config) + stage = "3 Fwd" and + n = 30 and + Stage3::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "3 Rev" and n = 35 and Stage3::stats(false, nodes, fields, conscand, tuples, config) + stage = "3 Rev" and + n = 35 and + Stage3::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "4 Fwd" and n = 40 and Stage4::stats(true, nodes, fields, conscand, tuples, config) + stage = "4 Fwd" and + n = 40 and + Stage4::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "4 Rev" and n = 45 and Stage4::stats(false, nodes, fields, conscand, tuples, config) + stage = "4 Rev" and + n = 45 and + Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { @@ -3947,6 +3993,8 @@ private module FlowExploration { or additionalJumpStep(node1, node2, config) or + additionalJumpStateStep(node1, _, node2, _, config) + or // flow into callable viableParamArgEx(_, node2, node1) or @@ -3960,7 +4008,7 @@ private module FlowExploration { } private predicate interestingCallableSrc(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSource(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSource(n) or config.isSource(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSrc(mid, config) and callableStep(mid, c, config) @@ -3968,7 +4016,7 @@ private module FlowExploration { } private predicate interestingCallableSink(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSink(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSink(n) or config.isSink(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSink(mid, config) and callableStep(c, mid, config) @@ -3996,13 +4044,13 @@ private module FlowExploration { or exists(Node n, Configuration config | ce1 = TCallableSrc() and - config.isSource(n) and + (config.isSource(n) or config.isSource(n, _)) and ce2 = TCallable(getNodeEnclosingCallable(n), config) ) or exists(Node n, Configuration config | ce2 = TCallableSink() and - config.isSink(n) and + (config.isSink(n) or config.isSink(n, _)) and ce1 = TCallable(getNodeEnclosingCallable(n), config) ) } @@ -4104,13 +4152,26 @@ private module FlowExploration { } } + private predicate relevantState(FlowState state) { + sourceNode(_, state, _) or + sinkNode(_, state, _) or + additionalLocalStateStep(_, state, _, _, _) or + additionalLocalStateStep(_, _, _, state, _) or + additionalJumpStateStep(_, state, _, _, _) or + additionalJumpStateStep(_, _, _, state, _) + } + private newtype TSummaryCtx1 = TSummaryCtx1None() or TSummaryCtx1Param(ParamNodeEx p) private newtype TSummaryCtx2 = TSummaryCtx2None() or - TSummaryCtx2Some(PartialAccessPath ap) + TSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TSummaryCtx3 = + TSummaryCtx3None() or + TSummaryCtx3Some(PartialAccessPath ap) private newtype TRevSummaryCtx1 = TRevSummaryCtx1None() or @@ -4118,52 +4179,66 @@ private module FlowExploration { private newtype TRevSummaryCtx2 = TRevSummaryCtx2None() or - TRevSummaryCtx2Some(RevPartialAccessPath ap) + TRevSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TRevSummaryCtx3 = + TRevSummaryCtx3None() or + TRevSummaryCtx3Some(RevPartialAccessPath ap) private newtype TPartialPathNode = TPartialPathNodeFwd( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = TPartialNil(node.getDataFlowType()) and - not fullBarrier(node, config) and exists(config.explorationLimit()) or - partialPathNodeMk0(node, cc, sc1, sc2, ap, config) and + partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, ap, config) and distSrc(node.getEnclosingCallable(), config) <= config.explorationLimit() } or TPartialPathNodeRev( - NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, RevPartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, TRevSummaryCtx3 sc3, + RevPartialAccessPath ap, Configuration config ) { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() and - not fullBarrier(node, config) and exists(config.explorationLimit()) or exists(PartialPathNodeRev mid | - revPartialPathStep(mid, node, sc1, sc2, ap, config) and - not clearsContentCached(node.asNode(), ap.getHead()) and + revPartialPathStep(mid, node, state, sc1, sc2, sc3, ap, config) and + not clearsContentEx(node, ap.getHead()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead()) + ) and not fullBarrier(node, config) and + not stateBarrier(node, state, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) } pragma[nomagic] private predicate partialPathNodeMk0( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid | - partialPathStep(mid, node, cc, sc1, sc2, ap, config) and + partialPathStep(mid, node, state, cc, sc1, sc2, sc3, ap, config) and not fullBarrier(node, config) and - not clearsContentCached(node.asNode(), ap.getHead().getContent()) and + not stateBarrier(node, state, config) and + not clearsContentEx(node, ap.getHead().getContent()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead().getContent()) + ) and if node.asNode() instanceof CastingNode then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() @@ -4201,6 +4276,8 @@ private module FlowExploration { /** Gets the underlying `Node`. */ final Node getNode() { this.getNodeEx().projectToNode() = result } + FlowState getState() { none() } + private NodeEx getNodeEx() { result = this.(PartialPathNodeFwd).getNodeEx() or result = this.(PartialPathNodeRev).getNodeEx() @@ -4258,135 +4335,182 @@ private module FlowExploration { private class PartialPathNodeFwd extends PartialPathNode, TPartialPathNodeFwd { NodeEx node; + FlowState state; CallContext cc; TSummaryCtx1 sc1; TSummaryCtx2 sc2; + TSummaryCtx3 sc3; PartialAccessPath ap; Configuration config; - PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, cc, sc1, sc2, ap, config) } + PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, state, cc, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } TSummaryCtx1 getSummaryCtx1() { result = sc1 } TSummaryCtx2 getSummaryCtx2() { result = sc2 } + TSummaryCtx3 getSummaryCtx3() { result = sc3 } + PartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeFwd getASuccessor() { - partialPathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx1(), - result.getSummaryCtx2(), result.getAp(), result.getConfiguration()) + partialPathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx1(), result.getSummaryCtx2(), result.getSummaryCtx3(), result.getAp(), + result.getConfiguration()) } predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap instanceof TPartialNil } } private class PartialPathNodeRev extends PartialPathNode, TPartialPathNodeRev { NodeEx node; + FlowState state; TRevSummaryCtx1 sc1; TRevSummaryCtx2 sc2; + TRevSummaryCtx3 sc3; RevPartialAccessPath ap; Configuration config; - PartialPathNodeRev() { this = TPartialPathNodeRev(node, sc1, sc2, ap, config) } + PartialPathNodeRev() { this = TPartialPathNodeRev(node, state, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + TRevSummaryCtx1 getSummaryCtx1() { result = sc1 } TRevSummaryCtx2 getSummaryCtx2() { result = sc2 } + TRevSummaryCtx3 getSummaryCtx3() { result = sc3 } + RevPartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeRev getASuccessor() { - revPartialPathStep(result, this.getNodeEx(), this.getSummaryCtx1(), this.getSummaryCtx2(), - this.getAp(), this.getConfiguration()) + revPartialPathStep(result, this.getNodeEx(), this.getState(), this.getSummaryCtx1(), + this.getSummaryCtx2(), this.getSummaryCtx3(), this.getAp(), this.getConfiguration()) } predicate isSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() } } private predicate partialPathStep( - PartialPathNodeFwd mid, NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { not isUnreachableInCallCached(node.asNode(), cc.(CallContextSpecificCall).getCall()) and ( localFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc = mid.getCallContext() and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() ) or jumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc instanceof CallContextAny and + sc1 = TSummaryCtx1None() and + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() or partialPathStoreStep(mid, _, _, node, ap) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(PartialAccessPath ap0, TypedContent tc | partialPathReadStep(mid, ap0, tc, node, cc, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsFwd(ap, tc, ap0, config) ) or - partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config) + partialPathIntoCallable(mid, node, state, _, cc, sc1, sc2, sc3, _, ap, config) or - partialPathOutOfCallable(mid, node, cc, ap, config) and + partialPathOutOfCallable(mid, node, state, cc, ap, config) and sc1 = TSummaryCtx1None() and - sc2 = TSummaryCtx2None() + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() or - partialPathThroughCallable(mid, node, cc, ap, config) and + partialPathThroughCallable(mid, node, state, cc, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } bindingset[result, i] - private int unbindInt(int i) { i <= result and i >= result } + private int unbindInt(int i) { pragma[only_bind_out](i) = pragma[only_bind_out](result) } pragma[inline] private predicate partialPathStoreStep( @@ -4429,10 +4553,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable0( - PartialPathNodeFwd mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, + PartialAccessPath ap, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and ap = mid.getAp() and @@ -4441,11 +4566,11 @@ private module FlowExploration { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, + PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - partialPathOutOfCallable0(mid, pos, innercc, ap, config) and + partialPathOutOfCallable0(mid, pos, state, innercc, ap, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -4455,10 +4580,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(ReturnKindExt kind, DataFlowCall call | - partialPathOutOfCallable1(mid, call, kind, cc, ap, config) + partialPathOutOfCallable1(mid, call, kind, state, cc, ap, config) | out.asNode() = kind.getAnOutNode(call) ) @@ -4466,37 +4592,40 @@ private module FlowExploration { pragma[noinline] private predicate partialPathIntoArg( - PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(ArgNode arg | + exists(ArgNode arg, ArgumentPosition apos | arg = mid.getNodeEx().asNode() and + state = mid.getState() and cc = mid.getCallContext() and - arg.argumentOf(call, i) and + arg.argumentOf(call, apos) and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate partialPathIntoCallable0( - PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc, - DataFlowCall call, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, PartialAccessPath ap, Configuration config ) { - partialPathIntoArg(mid, i, outercc, call, ap, config) and + partialPathIntoArg(mid, pos, state, outercc, call, ap, config) and callable = resolveCall(call, outercc) } private predicate partialPathIntoCallable( - PartialPathNodeFwd mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, - TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, + CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(int i, DataFlowCallable callable | - partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable | + partialPathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and sc1 = TSummaryCtx1Param(p) and - sc2 = TSummaryCtx2Some(ap) + sc2 = TSummaryCtx2Some(state) and + sc3 = TSummaryCtx3Some(ap) | if recordDataFlowCallSite(call, callable) then innercc = TSpecificCall(call) @@ -4506,15 +4635,17 @@ private module FlowExploration { pragma[nomagic] private predicate paramFlowsThroughInPartialPath( - ReturnKindExt kind, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid, RetNodeEx ret | mid.getNodeEx() = ret and kind = ret.getKind() and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() and ap = mid.getAp() ) @@ -4522,85 +4653,119 @@ private module FlowExploration { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc, + DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { - exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 | - partialPathIntoCallable(mid, _, cc, innercc, sc1, sc2, call, _, config) and - paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config) + exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3 | + partialPathIntoCallable(mid, _, _, cc, innercc, sc1, sc2, sc3, call, _, config) and + paramFlowsThroughInPartialPath(kind, state, innercc, sc1, sc2, sc3, ap, config) ) } private predicate partialPathThroughCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(DataFlowCall call, ReturnKindExt kind | - partialPathThroughCallable0(call, mid, kind, cc, ap, config) and + partialPathThroughCallable0(call, mid, kind, state, cc, ap, config) and out.asNode() = kind.getAnOutNode(call) ) } + pragma[nomagic] private predicate revPartialPathStep( - PartialPathNodeRev mid, NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, - RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, + TRevSummaryCtx3 sc3, RevPartialAccessPath ap, Configuration config ) { localFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or jumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = TRevSummaryCtx1None() and + sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or revPartialPathReadStep(mid, _, _, node, ap) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(RevPartialAccessPath ap0, Content c | revPartialPathStoreStep(mid, ap0, c, node, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsRev(ap, c, ap0, config) ) or exists(ParamNodeEx p | mid.getNodeEx() = p and viableParamArgEx(_, p, node) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() ) or exists(ReturnPosition pos | - revPartialPathIntoReturn(mid, pos, sc1, sc2, _, ap, config) and + revPartialPathIntoReturn(mid, pos, state, sc1, sc2, sc3, _, ap, config) and pos = getReturnPosition(node.asNode()) ) or - revPartialPathThroughCallable(mid, node, ap, config) and + revPartialPathThroughCallable(mid, node, state, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } pragma[inline] @@ -4643,14 +4808,17 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathIntoReturn( - PartialPathNodeRev mid, ReturnPosition pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, - DataFlowCall call, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, RevPartialAccessPath ap, + Configuration config ) { exists(NodeEx out | mid.getNodeEx() = out and + mid.getState() = state and viableReturnPosOutEx(call, pos, out) and sc1 = TRevSummaryCtx1Some(pos) and - sc2 = TRevSummaryCtx2Some(ap) and + sc2 = TRevSummaryCtx2Some(state) and + sc3 = TRevSummaryCtx3Some(ap) and ap = mid.getAp() and config = mid.getConfiguration() ) @@ -4658,36 +4826,40 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathFlowsThrough( - int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap, - Configuration config + ArgumentPosition apos, FlowState state, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, + TRevSummaryCtx3Some sc3, RevPartialAccessPath ap, Configuration config ) { - exists(PartialPathNodeRev mid, ParamNodeEx p | + exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos | mid.getNodeEx() = p and - p.getPosition() = pos and + mid.getState() = state and + p.getPosition() = ppos and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap, - Configuration config + DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, + RevPartialAccessPath ap, Configuration config ) { - exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 | - revPartialPathIntoReturn(mid, _, sc1, sc2, call, _, config) and - revPartialPathFlowsThrough(pos, sc1, sc2, ap, config) + exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | + revPartialPathIntoReturn(mid, _, _, sc1, sc2, sc3, call, _, config) and + revPartialPathFlowsThrough(pos, state, sc1, sc2, sc3, ap, config) ) } pragma[nomagic] private predicate revPartialPathThroughCallable( - PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ArgNodeEx node, FlowState state, RevPartialAccessPath ap, + Configuration config ) { - exists(DataFlowCall call, int pos | - revPartialPathThroughCallable0(call, mid, pos, ap, config) and + exists(DataFlowCall call, ArgumentPosition pos | + revPartialPathThroughCallable0(call, mid, pos, state, ap, config) and node.asNode().(ArgNode).argumentOf(call, pos) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 65408c9915a..1228d00b6ba 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -54,12 +54,23 @@ abstract class Configuration extends string { /** * Holds if `source` is a relevant data flow source. */ - abstract predicate isSource(Node source); + predicate isSource(Node source) { none() } + + /** + * Holds if `source` is a relevant data flow source with the given initial + * `state`. + */ + predicate isSource(Node source, FlowState state) { none() } /** * Holds if `sink` is a relevant data flow sink. */ - abstract predicate isSink(Node sink); + predicate isSink(Node sink) { none() } + + /** + * Holds if `sink` is a relevant data flow sink accepting `state`. + */ + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -67,6 +78,12 @@ abstract class Configuration extends string { */ predicate isBarrier(Node node) { none() } + /** + * Holds if data flow through `node` is prohibited when the flow state is + * `state`. + */ + predicate isBarrier(Node node, FlowState state) { none() } + /** Holds if data flow into `node` is prohibited. */ predicate isBarrierIn(Node node) { none() } @@ -81,16 +98,31 @@ abstract class Configuration extends string { deprecated predicate isBarrierGuard(BarrierGuard guard) { none() } /** - * Holds if the additional flow step from `node1` to `node2` must be taken - * into account in the analysis. + * DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead. + * + * Holds if data flow through nodes guarded by `guard` is prohibited when + * the flow state is `state` + */ + deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() } + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. */ predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + none() + } + /** * Holds if an arbitrary number of implicit read steps of content `c` may be * taken at `node`. */ - predicate allowImplicitRead(Node node, Content c) { none() } + predicate allowImplicitRead(Node node, ContentSet c) { none() } /** * Gets the virtual dispatch branching limit when calculating field flow. @@ -115,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -126,12 +164,14 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -144,6 +184,14 @@ abstract class Configuration extends string { */ int explorationLimit() { none() } + /** + * Holds if hidden nodes should be included in the data flow graph. + * + * This feature should only be used for debugging or when the data flow graph + * is not visualized (for example in a `path-problem` query). + */ + predicate includeHiddenNodes() { none() } + /** * Holds if there is a partial data flow path from `source` to `node`. The * approximate distance between `node` and the closest source is `dist` and @@ -201,10 +249,16 @@ abstract private class ConfigurationRecursionPrevention extends Configuration { override predicate hasFlow(Node source, Node sink) { strictcount(Node n | this.isSource(n)) < 0 or + strictcount(Node n | this.isSource(n, _)) < 0 + or strictcount(Node n | this.isSink(n)) < 0 or + strictcount(Node n | this.isSink(n, _)) < 0 + or strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or + strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 + or super.hasFlow(source, sink) } } @@ -260,13 +314,11 @@ private class ArgNodeEx extends NodeEx { private class ParamNodeEx extends NodeEx { ParamNodeEx() { this.asNode() instanceof ParamNode } - predicate isParameterOf(DataFlowCallable c, int i) { - this.asNode().(ParamNode).isParameterOf(c, i) + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + this.asNode().(ParamNode).isParameterOf(c, pos) } - int getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } + ParameterPosition getPosition() { this.isParameterOf(_, result) } } private class RetNodeEx extends NodeEx { @@ -280,22 +332,26 @@ private class RetNodeEx extends NodeEx { private predicate inBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierIn(n) and - config.isSource(n) + config.isBarrierIn(n) + | + config.isSource(n) or config.isSource(n, _) ) } private predicate outBarrier(NodeEx node, Configuration config) { exists(Node n | node.asNode() = n and - config.isBarrierOut(n) and - config.isSink(n) + config.isBarrierOut(n) + | + config.isSink(n) or config.isSink(n, _) ) } /** A bridge class to access the deprecated `isBarrierGuard`. */ private class BarrierGuardGuardedNodeBridge extends Unit { abstract predicate guardedNode(Node n, Configuration config); + + abstract predicate guardedNode(Node n, FlowState state, Configuration config); } private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { @@ -305,6 +361,13 @@ private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge { n = g.getAGuardedNode() ) } + + deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) { + exists(BarrierGuard g | + config.isBarrierGuard(g, state) and + n = g.getAGuardedNode() + ) + } } pragma[nomagic] @@ -313,23 +376,47 @@ private predicate fullBarrier(NodeEx node, Configuration config) { config.isBarrier(n) or config.isBarrierIn(n) and - not config.isSource(n) + not config.isSource(n) and + not config.isSource(n, _) or config.isBarrierOut(n) and - not config.isSink(n) + not config.isSink(n) and + not config.isSink(n, _) or any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config) ) } pragma[nomagic] -private predicate sourceNode(NodeEx node, Configuration config) { - config.isSource(node.asNode()) and - not fullBarrier(node, config) +private predicate stateBarrier(NodeEx node, FlowState state, Configuration config) { + exists(Node n | node.asNode() = n | + config.isBarrier(n, state) + or + any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config) + ) } pragma[nomagic] -private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) } +private predicate sourceNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSource(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSource(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} + +pragma[nomagic] +private predicate sinkNode(NodeEx node, FlowState state, Configuration config) { + ( + config.isSink(node.asNode()) and state instanceof FlowStateEmpty + or + config.isSink(node.asNode(), state) + ) and + not fullBarrier(node, config) and + not stateBarrier(node, state, config) +} /** Provides the relevant barriers for a step from `node1` to `node2`. */ pragma[inline] @@ -347,7 +434,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -366,7 +453,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -379,6 +466,20 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat ) } +private predicate additionalLocalStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) + ) +} + /** * Holds if data can flow from `node1` to `node2` in a way that discards call contexts. */ @@ -386,7 +487,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -399,15 +500,31 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) } -private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { - read(node1.asNode(), c, node2.asNode()) and +private predicate additionalJumpStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, Configuration config +) { + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and + stepFilter(node1, node2, config) and + not stateBarrier(node1, s1, config) and + not stateBarrier(node2, s2, config) and + not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext + ) +} + +pragma[nomagic] +private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -417,11 +534,46 @@ private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration conf ) } +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(ContentSet cs | + readSet(node1, cs, node2, config) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate clearsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + clearsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +// inline to reduce fan-out via `getAReadContent` +bindingset[c] +private predicate expectsContentEx(NodeEx n, Content c) { + exists(ContentSet cs | + expectsContentCached(n.asNode(), cs) and + pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent() + ) +} + +pragma[nomagic] +private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) } + +pragma[nomagic] +private predicate hasReadStep(Content c, Configuration config) { read(_, c, _, config) } + +pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and - read(_, tc.getContent(), _, config) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and + hasReadStep(tc.getContent(), config) and stepFilter(node1, node2, config) } @@ -454,14 +606,29 @@ private predicate hasSinkCallCtx(Configuration config) { ) } -private module Stage1 { - class ApApprox = Unit; +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} - class Ap = Unit; +private module Stage1 implements StageSig { + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } - class ApOption = Unit; - - class Cc = boolean; + private class Cc = boolean; /* Begin: Stage 1 logic. */ /** @@ -470,30 +637,20 @@ private module Stage1 { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { - sourceNode(node, config) and + private predicate fwdFlow(NodeEx node, Cc cc, Configuration config) { + sourceNode(node, _, config) and if hasSourceCallCtx(config) then cc = true else cc = false or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - localFlowStep(mid, node, config) + exists(NodeEx mid | fwdFlow(mid, cc, config) | + localFlowStep(mid, node, config) or + additionalLocalFlowStep(mid, node, config) or + additionalLocalStateStep(mid, _, node, _, config) ) or - exists(NodeEx mid | - fwdFlow(mid, cc, config) and - additionalLocalFlowStep(mid, node, config) - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - jumpStep(mid, node, config) and - cc = false - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, config) and - additionalJumpStep(mid, node, config) and - cc = false + exists(NodeEx mid | fwdFlow(mid, _, config) and cc = false | + jumpStep(mid, node, config) or + additionalJumpStep(mid, node, config) or + additionalJumpStateStep(mid, _, node, _, config) ) or // store @@ -504,9 +661,9 @@ private module Stage1 { ) or // read - exists(Content c | - fwdFlowRead(c, node, cc, config) and - fwdFlowConsCand(c, config) + exists(ContentSet c | + fwdFlowReadSet(c, node, cc, config) and + fwdFlowConsCandSet(c, _, config) ) or // flow into a callable @@ -530,10 +687,10 @@ private module Stage1 { private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) } pragma[nomagic] - private predicate fwdFlowRead(Content c, NodeEx node, Cc cc, Configuration config) { + private predicate fwdFlowReadSet(ContentSet c, NodeEx node, Cc cc, Configuration config) { exists(NodeEx mid | fwdFlow(mid, cc, config) and - read(mid, c, node, config) + readSet(mid, c, node, config) ) } @@ -551,6 +708,16 @@ private module Stage1 { ) } + /** + * Holds if `cs` may be interpreted in a read as the target of some store + * into `c`, in the flow covered by `fwdFlow`. + */ + pragma[nomagic] + private predicate fwdFlowConsCandSet(ContentSet cs, Content c, Configuration config) { + fwdFlowConsCand(c, config) and + c = cs.getAReadContent() + } + pragma[nomagic] private predicate fwdFlowReturnPosition(ReturnPosition pos, Cc cc, Configuration config) { exists(RetNodeEx ret | @@ -584,6 +751,24 @@ private module Stage1 { ) } + private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1 | + additionalLocalStateStep(node1, state1, _, state2, config) or + additionalJumpStateStep(node1, state1, _, state2, config) + | + fwdFlow(node1, config) + ) + } + + private predicate fwdFlowState(FlowState state, Configuration config) { + sourceNode(_, state, config) + or + exists(FlowState state0 | + fwdFlowState(state0, config) and + stateStepFwd(state0, state, config) + ) + } + /** * Holds if `node` is part of a path from a source to a sink in the * configuration `config`. @@ -592,37 +777,30 @@ private module Stage1 { * the enclosing callable in order to reach a sink. */ pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { + private predicate revFlow(NodeEx node, boolean toReturn, Configuration config) { revFlow0(node, toReturn, config) and fwdFlow(node, config) } pragma[nomagic] private predicate revFlow0(NodeEx node, boolean toReturn, Configuration config) { - fwdFlow(node, config) and - sinkNode(node, config) and - if hasSinkCallCtx(config) then toReturn = true else toReturn = false - or - exists(NodeEx mid | - localFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(FlowState state | + fwdFlow(node, pragma[only_bind_into](config)) and + sinkNode(node, state, config) and + fwdFlowState(state, pragma[only_bind_into](config)) and + if hasSinkCallCtx(config) then toReturn = true else toReturn = false ) or - exists(NodeEx mid | - additionalLocalFlowStep(node, mid, config) and - revFlow(mid, toReturn, config) + exists(NodeEx mid | revFlow(mid, toReturn, config) | + localFlowStep(node, mid, config) or + additionalLocalFlowStep(node, mid, config) or + additionalLocalStateStep(node, _, mid, _, config) ) or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false - ) - or - exists(NodeEx mid | - additionalJumpStep(node, mid, config) and - revFlow(mid, _, config) and - toReturn = false + exists(NodeEx mid | revFlow(mid, _, config) and toReturn = false | + jumpStep(node, mid, config) or + additionalJumpStep(node, mid, config) or + additionalJumpStateStep(node, _, mid, _, config) ) or // store @@ -632,9 +810,9 @@ private module Stage1 { ) or // read - exists(NodeEx mid, Content c | - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + exists(NodeEx mid, ContentSet c | + readSet(node, c, mid, config) and + fwdFlowConsCandSet(c, _, pragma[only_bind_into](config)) and revFlow(mid, toReturn, pragma[only_bind_into](config)) ) or @@ -660,10 +838,10 @@ private module Stage1 { */ pragma[nomagic] private predicate revFlowConsCand(Content c, Configuration config) { - exists(NodeEx mid, NodeEx node | + exists(NodeEx mid, NodeEx node, ContentSet cs | fwdFlow(node, pragma[only_bind_into](config)) and - read(node, c, mid, config) and - fwdFlowConsCand(c, pragma[only_bind_into](config)) and + readSet(node, cs, mid, config) and + fwdFlowConsCandSet(cs, c, pragma[only_bind_into](config)) and revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config)) ) } @@ -682,13 +860,14 @@ private module Stage1 { * Holds if `c` is the target of both a read and a store in the flow covered * by `revFlow`. */ - private predicate revFlowIsReadAndStored(Content c, Configuration conf) { + pragma[nomagic] + additional predicate revFlowIsReadAndStored(Content c, Configuration conf) { revFlowConsCand(c, conf) and revFlowStore(c, _, _, conf) } pragma[nomagic] - predicate viableReturnPosOutNodeCandFwd1( + additional predicate viableReturnPosOutNodeCandFwd1( DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config ) { fwdFlowReturnPosition(pos, _, config) and @@ -704,7 +883,7 @@ private module Stage1 { } pragma[nomagic] - predicate viableParamArgNodeCandFwd1( + additional predicate viableParamArgNodeCandFwd1( DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config ) { viableParamArgEx(call, p, arg) and @@ -739,6 +918,31 @@ private module Stage1 { ) } + private predicate stateStepRev(FlowState state1, FlowState state2, Configuration config) { + exists(NodeEx node1, NodeEx node2 | + additionalLocalStateStep(node1, state1, node2, state2, config) or + additionalJumpStateStep(node1, state1, node2, state2, config) + | + revFlow(node1, _, pragma[only_bind_into](config)) and + revFlow(node2, _, pragma[only_bind_into](config)) and + fwdFlowState(state1, pragma[only_bind_into](config)) and + fwdFlowState(state2, pragma[only_bind_into](config)) + ) + } + + additional predicate revFlowState(FlowState state, Configuration config) { + exists(NodeEx node | + sinkNode(node, state, config) and + revFlow(node, _, pragma[only_bind_into](config)) and + fwdFlowState(state, pragma[only_bind_into](config)) + ) + or + exists(FlowState state0 | + revFlowState(state0, config) and + stateStepRev(state, state0, config) + ) + } + pragma[nomagic] predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -756,15 +960,24 @@ private module Stage1 { pragma[nomagic] predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config) { revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and - revFlow(n2, pragma[only_bind_into](config)) and - read(n1, c, n2, pragma[only_bind_into](config)) + read(n1, c, n2, pragma[only_bind_into](config)) and + revFlow(n2, pragma[only_bind_into](config)) } pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow(node, toReturn, config) and exists(returnAp) and exists(ap) + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, _, pragma[only_bind_into](config)) and + exists(state) and + exists(ap) } private predicate throughFlowNodeCand(NodeEx node, Configuration config) { @@ -791,21 +1004,26 @@ private module Stage1 { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -815,17 +1033,21 @@ private module Stage1 { ) } - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { + additional predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { fwd = true and nodes = count(NodeEx node | fwdFlow(node, config)) and fields = count(Content f0 | fwdFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | fwdFlowState(state, config)) and tuples = count(NodeEx n, boolean b | fwdFlow(n, b, config)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, config)) and fields = count(Content f0 | revFlowConsCand(f0, config)) and conscand = -1 and + states = count(FlowState state | revFlowState(state, config)) and tuples = count(NodeEx n, boolean b | revFlow(n, b, config)) } /* End: Stage 1 logic. */ @@ -858,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -893,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -905,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -921,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -942,575 +1171,979 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false ) } -private module Stage2 { - module PrevStage = Stage1; +private signature module StageSig { + class Ap; + predicate revFlow(NodeEx node, Configuration config); + + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + + bindingset[node, state, config] + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); + + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); + + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); + + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ); + + predicate readStepCand(NodeEx n1, Content c, NodeEx n2, Configuration config); +} + +private module MkStage { class ApApprox = PrevStage::Ap; - class Ap = boolean; + signature module StageParam { + class Ap; - class ApNil extends Ap { - ApNil() { this = false } + class ApNil extends Ap; + + bindingset[result, ap] + ApApprox getApprox(Ap ap); + + ApNil getApNil(NodeEx node); + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail); + + Content getHeadContent(Ap ap); + + class ApOption; + + ApOption apNone(); + + ApOption apSome(Ap ap); + + class Cc; + + class CcCall extends Cc; + + // TODO: member predicate on CcCall + predicate matchesCall(CcCall cc, DataFlowCall call); + + class CcNoCall extends Cc; + + Cc ccNone(); + + CcCall ccSomeCall(); + + class LocalCc; + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc); + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc); + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc); + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ); + + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config + ); + + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + ); + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config); + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType); } - bindingset[result, ap] - private ApApprox getApprox(Ap ap) { any() } + module Stage implements StageSig { + import Param - private ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and exists(result) } + /* Begin: Stage logic. */ + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } - bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } - pragma[inline] - private Content getHeadContent(Ap ap) { exists(result) and ap = true } + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } - class ApOption = BooleanOption; + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, + ApApprox argApa, ApApprox apa, Configuration config + ) { + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) + } - ApOption apNone() { result = TBooleanNone() } + /** + * Holds if `node` is reachable with access path `ap` from a source in the + * configuration `config`. + * + * The call context `cc` records whether the node is reached through an + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. + */ + pragma[nomagic] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config + ) { + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and + filter(node, state, ap, config) + } - ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] + private predicate fwdFlow0( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config + ) { + sourceNode(node, state, config) and + (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and + argAp = apNone() and + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) + or + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and + localCc = getLocalCc(mid, cc) + | + localStep(mid, state0, node, state, true, _, config, localCc) and + ap = ap0 and + apa = apa0 + or + localStep(mid, state0, node, state, false, ap, config, localCc) and + ap0 instanceof ApNil and + apa = getApprox(ap) + ) + or + exists(NodeEx mid | + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and + jumpStep(mid, node, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStep(mid, node, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() and + ap = getApNil(node) and + apa = getApprox(ap) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and + additionalJumpStateStep(mid, state0, node, state, config) and + cc = ccNone() and + summaryCtx = TParamNodeNone() and + argAp = apNone() and + ap = getApNil(node) and + apa = getApprox(ap) + ) + or + // store + exists(TypedContent tc, Ap ap0 | + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) + ) + or + // read + exists(Ap ap0, Content c | + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) + ) + or + // flow into a callable + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() + ) + or + // flow out of a callable + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + or + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowStore( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and + typecheckStore(ap1, contentType) + ) + } + + /** + * Holds if forward flow with access path `tail` reaches a store of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(TypedContent tc | + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and + tc.getContent() = c and + cons = apCons(tc, tail) + ) + } + + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + + pragma[nomagic] + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, + Configuration config + ) { + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, c, node2, config) and + getHeadContent(ap) = c + } + + pragma[nomagic] + private predicate fwdFlowIn( + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config + ) { + exists(ArgNodeEx arg, boolean allowsFieldFlow | + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config + ) { + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) + ) + } + + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) + } + + /** + * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` + * and data might flow through the target callable and back out at `call`. + */ + pragma[nomagic] + private predicate fwdFlowIsEntered( + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config + ) { + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate storeStepFwd( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config + ) { + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and + ap2 = apCons(tc, ap1) and + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) + } + + private predicate readStepFwd( + NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config + ) { + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and + fwdFlowConsCand(ap1, c, ap2, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config + ) { + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config + ) { + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) + } + + /** + * Holds if `node` with access path `ap` is part of a path from a source to a + * sink in the configuration `config`. + * + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. + */ + pragma[nomagic] + additional predicate revFlow( + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config + ) { + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) + } + + pragma[nomagic] + private predicate revFlow0( + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, _, _, _, ap, config) and + sinkNode(node, state, config) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and + returnAp = apNone() and + ap instanceof ApNil + or + exists(NodeEx mid, FlowState state0 | + localStep(node, state, mid, state0, true, _, config, _) and + revFlow(mid, state0, returnCtx, returnAp, ap, config) + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and + localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and + ap instanceof ApNil + ) + or + exists(NodeEx mid | + jumpStep(node, mid, config) and + revFlow(mid, state, _, _, ap, config) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() + ) + or + exists(NodeEx mid, ApNil nil | + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStep(node, mid, config) and + revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() and + ap instanceof ApNil + ) + or + exists(NodeEx mid, FlowState state0, ApNil nil | + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and + additionalJumpStateStep(node, state, mid, state0, config) and + revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, + pragma[only_bind_into](config)) and + returnCtx = TReturnCtxNone() and + returnAp = apNone() and + ap instanceof ApNil + ) + or + // store + exists(Ap ap0, Content c | + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and + revFlowConsCand(ap0, c, ap, config) + ) + or + // read + exists(NodeEx mid, Ap ap0 | + revFlow(mid, state, returnCtx, returnAp, ap0, config) and + readStepFwd(node, ap, _, mid, ap0, config) + ) + or + // flow into a callable + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) + or + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) + ) + or + // flow out of a callable + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) + } + + pragma[nomagic] + private predicate revFlowStore( + Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, + ReturnCtx returnCtx, ApOption returnAp, Configuration config + ) { + revFlow(mid, state, returnCtx, returnAp, ap0, config) and + storeStepFwd(node, ap, tc, mid, ap0, config) and + tc.getContent() = c + } + + /** + * Holds if reverse flow with access path `tail` reaches a read of `c` + * resulting in access path `cons`. + */ + pragma[nomagic] + private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { + exists(NodeEx mid, Ap tail0 | + revFlow(mid, _, _, _, tail, config) and + tail = pragma[only_bind_into](tail0) and + readStepFwd(_, cons, c, mid, tail0, config) + ) + } + + pragma[nomagic] + private predicate revFlowOut( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config + ) { + exists(NodeEx out, boolean allowsFieldFlow | + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) + } + + pragma[nomagic] + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config + ) { + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) + } + + pragma[nomagic] + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config + ) { + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) + } + + /** + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. + */ + pragma[nomagic] + private predicate revFlowIsReturned( + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config + ) { + exists(RetNodeEx ret, FlowState state, CcCall ccc | + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and + matchesCall(ccc, call) + ) + } + + pragma[nomagic] + predicate storeStepCand( + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, + Configuration config + ) { + exists(Ap ap2, Content c | + PrevStage::storeStepCand(node1, _, tc, node2, contentType, config) and + revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _, config) and + revFlowConsCand(ap2, c, ap1, config) + ) + } + + predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { + exists(Ap ap1, Ap ap2 | + revFlow(node2, _, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and + readStepFwd(node1, ap1, c, node2, ap2, config) and + revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, + pragma[only_bind_into](config)) + ) + } + + additional predicate revFlow(NodeEx node, FlowState state, Configuration config) { + revFlow(node, state, _, _, _, config) + } + + predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, _, _, ap, config) + } + + pragma[nomagic] + predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + additional predicate revFlowAlias(NodeEx node, Configuration config) { + revFlow(node, _, _, _, _, config) + } + + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) { + revFlow(node, state, ap, config) + } + + private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepFwd(_, ap, tc, _, _, config) + } + + private predicate revConsCand(TypedContent tc, Ap ap, Configuration config) { + storeStepCand(_, ap, tc, _, _, config) + } + + private predicate validAp(Ap ap, Configuration config) { + revFlow(_, _, _, _, ap, config) and ap instanceof ApNil + or + exists(TypedContent head, Ap tail | + consCand(head, tail, config) and + ap = apCons(head, tail) + ) + } + + additional predicate consCand(TypedContent tc, Ap ap, Configuration config) { + revConsCand(tc, ap, config) and + validAp(ap, config) + } + + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config + ) { + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) + } + + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) + ) + } + + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) + ) + } + + additional predicate stats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config + ) { + fwd = true and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and + fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) + ) + or + fwd = false and + nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and + fields = count(TypedContent f0 | consCand(f0, _, config)) and + conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and + states = count(FlowState state | revFlow(_, state, _, _, _, config)) and + tuples = + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) + ) + } + /* End: Stage logic. */ + } +} + +private module BooleanCallContext { + class Cc extends boolean { + Cc() { this in [true, false] } + } + + class CcCall extends Cc { + CcCall() { this = true } + } + + /** Holds if the call context may be `call`. */ + predicate matchesCall(CcCall cc, DataFlowCall call) { any() } + + class CcNoCall extends Cc { + CcNoCall() { this = false } + } + + Cc ccNone() { result = false } + + CcCall ccSomeCall() { result = true } + + class LocalCc = Unit; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + + bindingset[call, c, innercc] + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } +} + +private module Level1CallContext { class Cc = CallContext; class CcCall = CallContextCall; + pragma[inline] + predicate matchesCall(CcCall cc, DataFlowCall call) { cc.matchesCall(call) } + class CcNoCall = CallContextNoCall; Cc ccNone() { result instanceof CallContextAny } CcCall ccSomeCall() { result instanceof CallContextSomeCall } - private class LocalCc = Unit; + module NoLocalCallContext { + class LocalCc = Unit; - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSiteDispatch(call, c) - then result = TSpecificCall(call) - else result = TSomeCall() + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { any() } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } + } + + module LocalCallContext { + class LocalCc = LocalCallContext; + + bindingset[node, cc] + LocalCc getLocalCc(NodeEx node, Cc cc) { + result = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + node.getEnclosingCallable()) + } + + bindingset[call, c, outercc] + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() + } } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { checkCallContextReturn(innercc, c, call) and if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() } +} - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } +private module Stage2Param implements MkStage::StageParam { + private module PrevStage = Stage1; - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + class Ap extends boolean { + Ap() { this in [true, false] } + } + + class ApNil extends Ap { + ApNil() { this = false } + } + + bindingset[result, ap] + PrevStage::Ap getApprox(Ap ap) { any() } + + ApNil getApNil(NodeEx node) { Stage1::revFlow(node, _) and exists(result) } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) } + + pragma[inline] + Content getHeadContent(Ap ap) { exists(result) and ap = true } + + class ApOption = BooleanOption; + + ApOption apNone() { result = TBooleanNone() } + + ApOption apSome(Ap ap) { result = TBooleanSome(ap) } + + import Level1CallContext + import NoLocalCallContext + + bindingset[node1, state1, config] + bindingset[node2, state2, config] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { ( preservesValue = true and - localFlowStepNodeCand1(node1, node2, config) + localFlowStepNodeCand1(node1, node2, config) and + state1 = state2 or preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, config) + additionalLocalFlowStepNodeCand1(node1, node2, config) and + state1 = state2 + or + preservesValue = false and + additionalLocalStateStep(node1, state1, node2, state2, config) ) and exists(ap) and exists(lcc) } - private predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; - private predicate flowIntoCall = flowIntoCallNodeCand1/5; + predicate flowIntoCall = flowIntoCallNodeCand1/5; - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and + expectsContentEx(node, c) + ) + } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + PrevStage::revFlowState(state, pragma[only_bind_into](config)) and + exists(ap) and + not stateBarrier(node, state, config) and + ( + notExpectsContent(node) + or + ap = true and + expectsContentCand(node, config) + ) + } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } +} - /* Begin: Stage 2 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 2 logic. */ +private module Stage2 implements StageSig { + import MkStage::Stage } pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } pragma[nomagic] @@ -1520,7 +2153,7 @@ private predicate flowIntoCallNodeCand2( ) { flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and - Stage2::revFlow(node1, pragma[only_bind_into](config)) + Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } private module LocalFlowBigStep { @@ -1531,7 +2164,8 @@ private module LocalFlowBigStep { private class FlowCheckNode extends NodeEx { FlowCheckNode() { castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) + clearsContentCached(this.asNode(), _) or + expectsContentCached(this.asNode(), _) } } @@ -1539,17 +2173,31 @@ private module LocalFlowBigStep { * Holds if `node` can be the first node in a maximal subsequence of local * flow steps in a dataflow path. */ - predicate localFlowEntry(NodeEx node, Configuration config) { - Stage2::revFlow(node, config) and + private predicate localFlowEntry(NodeEx node, FlowState state, Configuration config) { + Stage2::revFlow(node, state, config) and ( - sourceNode(node, config) or - jumpStep(_, node, config) or - additionalJumpStep(_, node, config) or - node instanceof ParamNodeEx or - node.asNode() instanceof OutNodeExt or - store(_, _, node, _, config) or - read(_, _, node, config) or + sourceNode(node, state, config) + or + jumpStep(_, node, config) + or + additionalJumpStep(_, node, config) + or + additionalJumpStateStep(_, _, node, state, config) + or + node instanceof ParamNodeEx + or + node.asNode() instanceof OutNodeExt + or + Stage2::storeStepCand(_, _, _, node, _, config) + or + Stage2::readStepCand(_, _, node, config) + or node instanceof FlowCheckNode + or + exists(FlowState s | + additionalLocalStateStep(_, s, node, state, config) and + s != state + ) ) } @@ -1557,28 +2205,42 @@ private module LocalFlowBigStep { * Holds if `node` can be the last node in a maximal subsequence of local * flow steps in a dataflow path. */ - private predicate localFlowExit(NodeEx node, Configuration config) { - exists(NodeEx next | Stage2::revFlow(next, config) | + private predicate localFlowExit(NodeEx node, FlowState state, Configuration config) { + exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or - store(node, _, next, _, config) or - read(node, _, next, config) + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or + Stage2::storeStepCand(node, _, _, next, _, config) or + Stage2::readStepCand(node, _, next, config) ) or + exists(NodeEx next, FlowState s | Stage2::revFlow(next, s, config) | + additionalJumpStateStep(node, state, next, s, config) + or + additionalLocalStateStep(node, state, next, s, config) and + s != state + ) + or + Stage2::revFlow(node, state, config) and node instanceof FlowCheckNode or - sinkNode(node, config) + sinkNode(node, state, config) } pragma[noinline] private predicate additionalLocalFlowStepNodeCand2( - NodeEx node1, NodeEx node2, Configuration config + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, Configuration config ) { additionalLocalFlowStepNodeCand1(node1, node2, config) and - Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and - Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config)) + state1 = state2 and + Stage2::revFlow(node1, pragma[only_bind_into](state1), false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, pragma[only_bind_into](state2), false, + pragma[only_bind_into](config)) + or + additionalLocalStateStep(node1, state1, node2, state2, config) and + Stage2::revFlow(node1, state1, false, pragma[only_bind_into](config)) and + Stage2::revFlowAlias(node2, state2, false, pragma[only_bind_into](config)) } /** @@ -1590,40 +2252,40 @@ private module LocalFlowBigStep { */ pragma[nomagic] private predicate localFlowStepPlus( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, Configuration config, - LocalCallContext cc + NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, + Configuration config, LocalCallContext cc ) { not isUnreachableInCallCached(node2.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and ( - localFlowEntry(node1, pragma[only_bind_into](config)) and + localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](config)) and ( localFlowStepNodeCand1(node1, node2, config) and preservesValue = true and - t = node1.getDataFlowType() // irrelevant dummy value + t = node1.getDataFlowType() and // irrelevant dummy value + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) or - additionalLocalFlowStepNodeCand2(node1, node2, config) and + additionalLocalFlowStepNodeCand2(node1, state, node2, state, config) and preservesValue = false and t = node2.getDataFlowType() ) and node1 != node2 and cc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + not isUnreachableInCallCached(node1.asNode(), cc.(LocalCallContextSpecificCall).getCall()) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and + localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue, t, + pragma[only_bind_into](config), cc) and localFlowStepNodeCand1(mid, node2, config) and not mid instanceof FlowCheckNode and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + Stage2::revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](config)) ) or exists(NodeEx mid | - localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and - additionalLocalFlowStepNodeCand2(mid, node2, config) and + localFlowStepPlus(node1, state, mid, _, _, pragma[only_bind_into](config), cc) and + additionalLocalFlowStepNodeCand2(mid, state, node2, state, config) and not mid instanceof FlowCheckNode and preservesValue = false and - t = node2.getDataFlowType() and - Stage2::revFlow(node2, pragma[only_bind_into](config)) + t = node2.getDataFlowType() ) ) } @@ -1634,36 +2296,121 @@ private module LocalFlowBigStep { */ pragma[nomagic] predicate localFlowBigStep( - NodeEx node1, NodeEx node2, boolean preservesValue, AccessPathFrontNil apf, - Configuration config, LocalCallContext callContext + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, node2, preservesValue, apf.getType(), config, callContext) and - localFlowExit(node2, config) + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and + localFlowExit(node2, state1, config) and + state1 = state2 + or + additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and + state1 != state2 and + preservesValue = false and + t = node2.getDataFlowType() and + callContext.relevantFor(node1.getEnclosingCallable()) and + not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | + isUnreachableInCallCached(node1.asNode(), call) or + isUnreachableInCallCached(node2.asNode(), call) + ) } } private import LocalFlowBigStep -private module Stage3 { - module PrevStage = Stage2; +private module Stage3Param implements MkStage::StageParam { + private module PrevStage = Stage2; - class ApApprox = PrevStage::Ap; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } + Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathFrontOption; @@ -1671,542 +2418,114 @@ private module Stage3 { ApOption apSome(Ap ap) { result = TAccessPathFrontSome(ap) } - class Cc = boolean; - - class CcCall extends Cc { - CcCall() { this = true } - - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } - - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } - - CcCall ccSomeCall() { result = true } - - private class LocalCc = Unit; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } - - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } - - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc - ) { - localFlowBigStep(node1, node2, preservesValue, ap, config, _) and exists(lcc) - } - - private predicate flowOutOfCall = flowOutOfCallNodeCand2/5; - - private predicate flowIntoCall = flowIntoCallNodeCand2/5; + import BooleanCallContext pragma[nomagic] - private predicate clear(NodeEx node, Ap ap) { ap.isClearedAt(node.asNode()) } + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) + } + + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { + PrevStage::revFlow(node, config) and + clearsContentCached(node.asNode(), c) + } + + pragma[nomagic] + private predicate clearContent(NodeEx node, Content c, Configuration config) { + exists(ContentSet cs | + PrevStage::readStepCand(_, pragma[only_bind_into](c), _, pragma[only_bind_into](config)) and + c = cs.getAReadContent() and + clearSet(node, cs, pragma[only_bind_into](config)) + ) + } + + pragma[nomagic] + private predicate clear(NodeEx node, Ap ap, Configuration config) { + clearContent(node, ap.getHead().getContent(), config) + } + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getHead().getContent() + ) + } pragma[nomagic] private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { - not clear(node, ap) and - if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + not clear(node, ap, config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) } bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { + predicate typecheckStore(Ap ap, DataFlowType contentType) { // We need to typecheck stores here, since reverse flow through a getter // might have a different type here compared to inside the getter. compatibleTypes(ap.getType(), contentType) } +} - /* Begin: Stage 3 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 3 logic. */ +private module Stage4 implements StageSig { + import MkStage::Stage } /** * Holds if `argApf` is recorded as the summary context for flow reaching `node` * and remains relevant for the following pruning stage. */ -private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { +private predicate flowCandSummaryCtx( + NodeEx node, FlowState state, AccessPathFront argApf, Configuration config +) { exists(AccessPathFront apf | - Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2216,12 +2535,12 @@ private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Config */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = - strictcount(NodeEx n | - Stage3::revFlow(n, _, _, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + strictcount(NodeEx n, FlowState state | + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or - flowCandSummaryCtx(n, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and @@ -2233,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2367,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2378,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2403,26 +2722,25 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4 { - module PrevStage = Stage3; - - class ApApprox = PrevStage::Ap; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; - private ApApprox getApprox(Ap ap) { result = ap.getFront() } + pragma[nomagic] + PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } - private ApNil getApNil(NodeEx node) { + ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TNil(node.getDataFlowType()) } bindingset[tc, tail] - private Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } + Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) } pragma[noinline] - private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } + Content getHeadContent(Ap ap) { result = ap.getHead().getContent() } class ApOption = AccessPathApproxOption; @@ -2430,559 +2748,88 @@ private module Stage4 { ApOption apSome(Ap ap) { result = TAccessPathApproxSome(ap) } - class Cc = CallContext; + import Level1CallContext + import LocalCallContext - class CcCall = CallContextCall; - - class CcNoCall = CallContextNoCall; - - Cc ccNone() { result instanceof CallContextAny } - - CcCall ccSomeCall() { result instanceof CallContextSomeCall } - - private class LocalCc = LocalCallContext; - - bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { - checkCallContextCall(outercc, call, c) and - if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall() - } - - bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { - checkCallContextReturn(innercc, c, call) and - if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() - } - - bindingset[node, cc, config] - private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { - localFlowEntry(node, config) and - result = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - node.getEnclosingCallable()) - } - - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, node2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] - private predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) } pragma[nomagic] - private predicate flowIntoCall( + predicate flowIntoCall( DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and - PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and - PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config)) + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) } - bindingset[node, ap] - private predicate filter(NodeEx node, Ap ap) { any() } + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { any() } // Type checking is not necessary here as it has already been done in stage 3. bindingset[ap, contentType] - private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } - - /* Begin: Stage 4 logic. */ - private predicate flowCand(NodeEx node, ApApprox apa, Configuration config) { - PrevStage::revFlow(node, _, _, apa, config) - } - - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - exists(ApApprox apa0 | - apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0) - ) - } - - pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config - ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - ccc.matchesCall(call) - } - - /** - * Holds if `node` is reachable with access path `ap` from a source in the - * configuration `config`. - * - * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. - */ - pragma[nomagic] - predicate fwdFlow(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - fwdFlow0(node, cc, argAp, ap, config) and - flowCand(node, unbindApa(getApprox(ap)), config) and - filter(node, ap) - } - - pragma[nomagic] - private predicate fwdFlow0(NodeEx node, Cc cc, ApOption argAp, Ap ap, Configuration config) { - flowCand(node, _, config) and - sourceNode(node, config) and - (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and - argAp = apNone() and - ap = getApNil(node) - or - exists(NodeEx mid, Ap ap0, LocalCc localCc | - fwdFlow(mid, cc, argAp, ap0, config) and - localCc = getLocalCc(mid, cc, config) - | - localStep(mid, node, true, _, config, localCc) and - ap = ap0 - or - localStep(mid, node, false, ap, config, localCc) and - ap0 instanceof ApNil - ) - or - exists(NodeEx mid | - fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - jumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and - flowCand(node, _, pragma[only_bind_into](config)) and - additionalJumpStep(mid, node, config) and - cc = ccNone() and - argAp = apNone() and - ap = getApNil(node) - ) - or - // store - exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, cc, argAp, config) and - ap = apCons(tc, ap0) - ) - or - // read - exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) - ) - or - // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() - ) - or - // flow out of a callable - fwdFlowOutNotFromArg(node, cc, argAp, ap, config) - or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) - } - - pragma[nomagic] - private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - exists(DataFlowType contentType | - fwdFlow(node1, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and - typecheckStore(ap1, contentType) - ) - } - - /** - * Holds if forward flow with access path `tail` reaches a store of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, config) and - tc.getContent() = c and - cons = apCons(tc, tail) - ) - } - - pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, Cc cc, ApOption argAp, Configuration config - ) { - fwdFlow(node1, cc, argAp, ap, config) and - PrevStage::readStepCand(node1, c, node2, config) and - getHeadContent(ap) = c - } - - pragma[nomagic] - private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, Cc outercc, Cc innercc, ApOption argAp, Ap ap, - Configuration config - ) { - exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, Cc ccOut, ApOption argAp, Ap ap, Configuration config - ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, Ap argAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` - * and data might flow through the target callable and back out at `call`. - */ - pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) - ) - } - - pragma[nomagic] - private predicate storeStepFwd( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config - ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, config) and - ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, config) - } - - private predicate readStepFwd( - NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config - ) { - fwdFlowRead(ap1, c, n1, n2, _, _, config) and - fwdFlowConsCand(ap1, c, ap2, config) - } - - pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) - ) - } - - pragma[nomagic] - private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config - ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) - } - - pragma[nomagic] - private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) { - fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config) - } - - /** - * Holds if `node` with access path `ap` is part of a path from a source to a - * sink in the configuration `config`. - * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. - */ - pragma[nomagic] - predicate revFlow(NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config) { - revFlow0(node, toReturn, returnAp, ap, config) and - fwdFlow(node, _, _, ap, config) - } - - pragma[nomagic] - private predicate revFlow0( - NodeEx node, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - fwdFlow(node, _, _, ap, config) and - sinkNode(node, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and - returnAp = apNone() and - ap instanceof ApNil - or - exists(NodeEx mid | - localStep(node, mid, true, _, config, _) and - revFlow(mid, toReturn, returnAp, ap, config) - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - localStep(node, mid, false, _, config, _) and - revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and - ap instanceof ApNil - ) - or - exists(NodeEx mid | - jumpStep(node, mid, config) and - revFlow(mid, _, _, ap, config) and - toReturn = false and - returnAp = apNone() - ) - or - exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and - additionalJumpStep(node, mid, config) and - revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and - returnAp = apNone() and - ap instanceof ApNil - ) - or - // store - exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, _, _, toReturn, returnAp, config) and - revFlowConsCand(ap0, c, ap, config) - ) - or - // read - exists(NodeEx mid, Ap ap0 | - revFlow(mid, toReturn, returnAp, ap0, config) and - readStepFwd(node, ap, _, mid, ap0, config) - ) - or - // flow into a callable - revFlowInNotToReturn(node, returnAp, ap, config) and - toReturn = false - or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - or - // flow out of a callable - revFlowOut(_, node, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() - } - - pragma[nomagic] - private predicate revFlowStore( - Ap ap0, Content c, Ap ap, NodeEx node, TypedContent tc, NodeEx mid, boolean toReturn, - ApOption returnAp, Configuration config - ) { - revFlow(mid, toReturn, returnAp, ap0, config) and - storeStepFwd(node, ap, tc, mid, ap0, config) and - tc.getContent() = c - } - - /** - * Holds if reverse flow with access path `tail` reaches a read of `c` - * resulting in access path `cons`. - */ - pragma[nomagic] - private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { - exists(NodeEx mid, Ap tail0 | - revFlow(mid, _, _, tail, config) and - tail = pragma[only_bind_into](tail0) and - readStepFwd(_, cons, c, mid, tail0, config) - ) - } - - pragma[nomagic] - private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config - ) { - exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, ApOption returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, Ap returnAp, Ap ap, Configuration config - ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) - } - - /** - * Holds if an output from `call` is reached in the flow covered by `revFlow` - * and data might flow through the target callable resulting in reverse flow - * reaching an argument of `call`. - */ - pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { - exists(RetNodeEx ret, CcCall ccc | - revFlowOut(call, ret, toReturn, returnAp, ap, config) and - fwdFlow(ret, ccc, apSome(_), ap, config) and - ccc.matchesCall(call) - ) - } - - pragma[nomagic] - predicate storeStepCand( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, - Configuration config - ) { - exists(Ap ap2, Content c | - store(node1, tc, node2, contentType, config) and - revFlowStore(ap2, c, ap1, node1, tc, node2, _, _, config) and - revFlowConsCand(ap2, c, ap1, config) - ) - } - - predicate readStepCand(NodeEx node1, Content c, NodeEx node2, Configuration config) { - exists(Ap ap1, Ap ap2 | - revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and - readStepFwd(node1, ap1, c, node2, ap2, config) and - revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, - pragma[only_bind_into](config)) - ) - } - - predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, config) } - - private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) { - storeStepFwd(_, ap, tc, _, _, config) - } - - predicate consCand(TypedContent tc, Ap ap, Configuration config) { - storeStepCand(_, ap, tc, _, _, config) - } - - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config - ) { - revFlow(p, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() - } - - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0), - pragma[only_bind_into](config)) and - fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) - ) - } - - pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, ArgNodeEx arg, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(arg, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) - } - - predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { - fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - tuples = count(NodeEx n, Cc cc, ApOption argAp, Ap ap | fwdFlow(n, cc, argAp, ap, config)) - or - fwd = false and - nodes = count(NodeEx node | revFlow(node, _, _, _, config)) and - fields = count(TypedContent f0 | consCand(f0, _, config)) and - conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and - tuples = count(NodeEx n, boolean b, ApOption retAp, Ap ap | revFlow(n, b, retAp, ap, config)) - } - /* End: Stage 4 logic. */ + predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } +private module Stage5 = MkStage::Stage; + bindingset[conf, result] private Configuration unbindConf(Configuration conf) { exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c)) } -private predicate nodeMayUseSummary(NodeEx n, AccessPathApprox apa, Configuration config) { - exists(DataFlowCallable c, AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, apa, _) and - Stage4::revFlow(n, true, _, apa0, config) and - Stage4::fwdFlow(n, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c +pragma[nomagic] +private predicate nodeMayUseSummary0( + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(AccessPathApprox apa0 | + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) + ) +} + +pragma[nomagic] +private predicate nodeMayUseSummary( + NodeEx n, FlowState state, AccessPathApprox apa, Configuration config +) { + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } private newtype TSummaryCtx = TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, AccessPath ap) { - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _) + TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { + exists(Configuration config | + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) + ) } /** @@ -3003,11 +2850,12 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { /** A summary context from which a flow summary can be generated. */ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { private ParamNodeEx p; + private FlowState s; private AccessPath ap; - SummaryCtxSome() { this = TSummaryCtxSome(p, ap) } + SummaryCtxSome() { this = TSummaryCtxSome(p, s, ap) } - int getParameterPos() { p.isParameterOf(_, result) } + ParameterPosition getParameterPos() { p.isParameterOf(_, result) } ParamNodeEx getParamNode() { result = p } @@ -3029,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -3037,8 +2885,8 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = - strictcount(NodeEx n | - Stage4::revFlow(n, _, _, apa, config) or nodeMayUseSummary(n, apa, config) + strictcount(NodeEx n, FlowState state | + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -3059,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -3082,6 +2930,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 @@ -3100,6 +2949,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 @@ -3134,10 +2984,13 @@ private newtype TAccessPath = } private newtype TPathNode = - TPathNodeMid(NodeEx node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) { + pragma[assume_small_delta] + TPathNodeMid( + NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config + ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, config) and - sourceNode(node, config) and + Stage5::revFlow(node, state, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall @@ -3148,15 +3001,28 @@ private newtype TPathNode = or // ... or a step from an existing PathNode to another node. exists(PathNodeMid mid | - pathStep(mid, node, cc, sc, ap) and + pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or - TPathNodeSink(NodeEx node, Configuration config) { + TPathNodeSink(NodeEx node, FlowState state, Configuration config) { exists(PathNodeMid sink | sink.isAtSink() and node = sink.getNodeEx() and + state = sink.getState() and + config = sink.getConfiguration() + ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and config = sink.getConfiguration() ) } @@ -3167,7 +3033,7 @@ private newtype TPathNode = * of dereference operations needed to get from the value in the node to the * tracked object. The final type indicates the type of the tracked object. */ -abstract private class AccessPath extends TAccessPath { +private class AccessPath extends TAccessPath { /** Gets the head of this access path, if any. */ abstract TypedContent getHead(); @@ -3228,6 +3094,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 @@ -3236,6 +3103,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) { @@ -3277,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -3308,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -3324,66 +3192,61 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { } } -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source are generated. - */ -class PathNode extends TPathNode { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - string toStringWithContext() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - none() - } - - /** Gets the underlying `Node`. */ - final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result } +abstract private class PathNodeImpl extends TPathNode { + /** Gets the `FlowState` of this node. */ + abstract FlowState getState(); /** Gets the associated configuration. */ - Configuration getConfiguration() { none() } - - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() - } + abstract Configuration getConfiguration(); /** Holds if this node is a source. */ - predicate isSource() { none() } -} + abstract predicate isSource(); -abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + pragma[nomagic] + private PathNodeImpl getANonHiddenSuccessor0() { + result = this.getASuccessorIfHidden*() and + not result.isHidden() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getANonHiddenSuccessor0() and + not this.isHidden() + } abstract NodeEx getNodeEx(); predicate isHidden() { - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink + not this.getConfiguration().includeHiddenNodes() and + ( + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + ) + } + + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) or - this.getNodeEx() instanceof TNodeImplicitRead + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup } private string ppAp() { @@ -3400,13 +3263,23 @@ abstract private class PathNodeImpl extends PathNode { result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" } - override string toString() { result = this.getNodeEx().toString() + this.ppAp() } + /** Gets a textual representation of this element. */ + string toString() { result = this.getNodeEx().toString() + this.ppAp() } - override string toStringWithContext() { - result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() - } + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() } - override predicate hasLocationInfo( + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) @@ -3414,31 +3287,93 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } -/** Holds if `n` can reach a sink or is used in a subpath. */ -private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } +/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ +private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} -private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) +private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2) + +/** + * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. + * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. + */ +class PathNode instanceof PathNodeImpl { + PathNode() { reach(this) } + + /** Gets a textual representation of this element. */ + final string toString() { result = super.toString() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + final string toStringWithContext() { result = super.toStringWithContext() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + final predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** Gets the underlying `Node`. */ + final Node getNode() { super.getNodeEx().projectToNode() = result } + + /** Gets the `FlowState` of this node. */ + final FlowState getState() { result = super.getState() } + + /** Gets the associated configuration. */ + final Configuration getConfiguration() { result = super.getConfiguration() } + + /** Gets a successor of this node, if any. */ + final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() } + + /** Holds if this node is a source. */ + final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } +} /** * Provides the query predicates needed to include a graph in a path-problem query. */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { - reach(n) and key = "semmle.label" and val = n.toString() + key = "semmle.label" and val = n.toString() } - query predicate subpaths = Subpaths::subpaths/4; + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + Subpaths::subpaths(arg, par, ret, out) + } } /** @@ -3447,15 +3382,18 @@ module PathGraph { */ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { NodeEx node; + FlowState state; CallContext cc; SummaryCtx sc; AccessPath ap; Configuration config; - PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) } + PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, ap, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } SummaryCtx getSummaryCtx() { result = sc } @@ -3465,8 +3403,8 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { override Configuration getConfiguration() { result = config } private PathNodeMid getSuccMid() { - pathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx(), - result.getAp()) and + pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx(), result.getAp()) and result.getConfiguration() = unbindConf(this.getConfiguration()) } @@ -3479,18 +3417,18 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { } override predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and ( if hasSourceCallCtx(config) then cc instanceof CallContextSomeCall else cc instanceof CallContextAny ) and sc instanceof SummaryCtxNone and - ap instanceof AccessPathNil + ap = TAccessPathNil(node.getDataFlowType()) } predicate isAtSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and ap instanceof AccessPathNil and if hasSinkCallCtx(config) then @@ -3512,6 +3450,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { PathNodeSink projectToSink() { this.isAtSink() and result.getNodeEx() = node and + result.getState() = state and result.getConfiguration() = unbindConf(config) } } @@ -3523,91 +3462,176 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid { */ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { NodeEx node; + FlowState state; Configuration config; - PathNodeSink() { this = TPathNodeSink(node, config) } + PathNodeSink() { this = TPathNodeSink(node, state, config) } override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } - override predicate isSource() { sourceNode(node, config) } + override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private predicate pathNode( + PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, + Configuration conf, LocalCallContext localCC +) { + midnode = mid.getNodeEx() and + state = mid.getState() and + conf = mid.getConfiguration() and + cc = mid.getCallContext() and + sc = mid.getSummaryCtx() and + localCC = + getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), + midnode.getEnclosingCallable()) and + ap = mid.getAp() } /** * 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, CallContext cc, SummaryCtx sc, AccessPath ap + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap ) { - exists(AccessPath ap0, NodeEx midnode, Configuration conf, LocalCallContext localCC | - midnode = mid.getNodeEx() and - conf = mid.getConfiguration() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - localCC = - getLocalCallContext(pragma[only_bind_into](pragma[only_bind_out](cc)), - midnode.getEnclosingCallable()) and - ap0 = mid.getAp() + exists(NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | + pathNode(mid, midnode, state0, cc, sc, ap, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, true, _, conf, localCC) + ) + or + exists( + AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | - localFlowBigStep(midnode, node, true, _, conf, localCC) and - ap = ap0 - or - localFlowBigStep(midnode, node, false, ap.getFront(), conf, localCC) and + pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or jumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and ap = mid.getAp() or additionalJumpStep(mid.getNodeEx(), node, mid.getConfiguration()) and + state = mid.getState() and cc instanceof CallContextAny and sc instanceof SummaryCtxNone and mid.getAp() instanceof AccessPathNil and ap = TAccessPathNil(node.getDataFlowType()) or - exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, mid.getConfiguration()) and + cc instanceof CallContextAny and + sc instanceof SummaryCtxNone and + mid.getAp() instanceof AccessPathNil and + ap = TAccessPathNil(node.getDataFlowType()) + or + exists(TypedContent tc | pathStoreStep(mid, node, state, ap.pop(tc), tc, cc)) and sc = mid.getSummaryCtx() or - exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and + exists(TypedContent tc | pathReadStep(mid, node, state, ap.push(tc), tc, cc)) and sc = mid.getSummaryCtx() or - pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp() + pathIntoCallable(mid, node, state, _, cc, sc, _, _) and ap = mid.getAp() or - pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone + pathOutOfCallable(mid, node, state, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone or - pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx() + pathThroughCallable(mid, node, state, cc, ap) and sc = mid.getSummaryCtx() } pragma[nomagic] private predicate pathReadStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } pragma[nomagic] private predicate pathStoreStep( - PathNodeMid mid, NodeEx node, AccessPath ap0, TypedContent tc, CallContext cc + PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + state = mid.getState() and cc = mid.getCallContext() } private predicate pathOutOfCallable0( - PathNodeMid mid, ReturnPosition pos, CallContext innercc, AccessPathApprox apa, + PathNodeMid mid, ReturnPosition pos, FlowState state, CallContext innercc, AccessPathApprox apa, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and apa = mid.getAp().getApprox() and @@ -3616,11 +3640,11 @@ private predicate pathOutOfCallable0( pragma[nomagic] private predicate pathOutOfCallable1( - PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, AccessPathApprox apa, - Configuration config + PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPathApprox apa, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - pathOutOfCallable0(mid, pos, innercc, apa, config) and + pathOutOfCallable0(mid, pos, state, innercc, apa, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -3634,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3642,9 +3666,9 @@ private NodeEx getAnOutNodeFlow( * is a return from a callable and is recorded by `cc`, if needed. */ pragma[noinline] -private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) { +private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, FlowState state, CallContext cc) { exists(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config | - pathOutOfCallable1(mid, call, kind, cc, apa, config) and + pathOutOfCallable1(mid, call, kind, state, cc, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3654,39 +3678,37 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc) */ pragma[noinline] private predicate pathIntoArg( - PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa, - Configuration config + PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call, + AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(ArgNode arg | - arg = mid.getNodeEx().asNode() and - cc = mid.getCallContext() and - arg.argumentOf(call, i) and - ap = mid.getAp() and + exists(ArgNodeEx arg, ArgumentPosition apos | + pathNode(mid, arg, state, cc, _, ap, config, _) and + arg.asNode().(ArgNode).argumentOf(call, apos) and apa = ap.getApprox() and - config = mid.getConfiguration() + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate parameterCand( - DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config + DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, _, apa, config) and - p.isParameterOf(callable, i) + Stage5::revFlow(p, _, apa, config) and + p.isParameterOf(callable, pos) ) } pragma[nomagic] private predicate pathIntoCallable0( - PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call, - AccessPath ap, Configuration config + PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, AccessPath ap, Configuration config ) { exists(AccessPathApprox apa | - pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa), - pragma[only_bind_into](config)) and + pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and callable = resolveCall(call, outercc) and - parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa), + parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa), pragma[only_bind_into](config)) ) } @@ -3698,16 +3720,16 @@ private predicate pathIntoCallable0( */ pragma[nomagic] private predicate pathIntoCallable( - PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc, - DataFlowCall call, Configuration config + PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, + SummaryCtx sc, DataFlowCall call, Configuration config ) { - exists(int i, DataFlowCallable callable, AccessPath ap | - pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap | + pathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and ( - sc = TSummaryCtxSome(p, ap) + sc = TSummaryCtxSome(p, state, ap) or - not exists(TSummaryCtxSome(p, ap)) and + not exists(TSummaryCtxSome(p, state, ap)) and sc = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also @@ -3724,35 +3746,25 @@ private predicate pathIntoCallable( /** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */ pragma[nomagic] private predicate paramFlowsThrough( - ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, - Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, + AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, int pos | - mid.getNodeEx() = ret and + exists(PathNodeMid mid, RetNodeEx ret | + pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - config = mid.getConfiguration() and - ap = mid.getAp() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } pragma[nomagic] private predicate pathThroughCallable0( - DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap, - AccessPathApprox apa, Configuration config + DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, + AccessPath ap, AccessPathApprox apa, Configuration config ) { exists(CallContext innercc, SummaryCtx sc | - pathIntoCallable(mid, _, cc, innercc, sc, call, config) and - paramFlowsThrough(kind, innercc, sc, ap, apa, config) + pathIntoCallable(mid, _, _, cc, innercc, sc, call, config) and + paramFlowsThrough(kind, state, innercc, sc, ap, apa, config) ) } @@ -3761,9 +3773,11 @@ private predicate pathThroughCallable0( * The context `cc` is restored to its value prior to entering the callable. */ pragma[noinline] -private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) { +private predicate pathThroughCallable( + PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, AccessPath ap +) { exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config | - pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and + pathThroughCallable0(call, mid, kind, state, cc, ap, apa, config) and out = getAnOutNodeFlow(kind, call, apa, config) ) } @@ -3776,47 +3790,44 @@ private module Subpaths { pragma[nomagic] private predicate subpaths01( PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + NodeEx out, FlowState sout, AccessPath apout ) { exists(Configuration config | - pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and - pathIntoCallable(arg, par, _, innercc, sc, _, config) and - paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and + pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, _, innercc, sc, _, config) and + paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc, + pragma[only_bind_into](apout), _, unbindConf(config)) and not arg.isHidden() ) } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `apout`, and `innercc`. + * `kind`, `sc`, `sout`, `apout`, and `innercc`. */ pragma[nomagic] private predicate subpaths02( - PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, - NodeEx out, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, FlowState sout, AccessPath apout ) { - subpaths01(arg, par, sc, innercc, kind, out, apout) and + subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and out.asNode() = kind.getAnOutNode(_) } pragma[nomagic] - private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() } /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple. */ pragma[nomagic] private predicate subpaths03( - PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout ) { exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | - subpaths02(arg, par, sc, innercc, kind, out, apout) and - ret.getNodeEx() = retnode and - kind = retnode.getKind() and - innercc = ret.getCallContext() and - sc = ret.getSummaryCtx() and - ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and - apout = ret.getAp() + subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and + pathNode(ret, retnode, sout, innercc, sc, apout, unbindConf(getPathNodeConf(arg)), _) and + kind = retnode.getKind() ) } @@ -3824,38 +3835,44 @@ private module Subpaths { n.getASuccessorImpl() = result and result.isHidden() and exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() | - localFlowBigStep(n1, n2, _, _, _, _) or + localFlowBigStep(n1, _, n2, _, _, _, _, _) or store(n1, _, n2, _, _) or - read(n1, _, n2, _) + readSet(n1, _, n2, _) ) } + pragma[nomagic] + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and + succNode = succ.getNodeEx() + } + /** * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) { - exists(ParamNodeEx p, NodeEx o, AccessPath apout | - pragma[only_bind_into](arg).getASuccessor() = par and - pragma[only_bind_into](arg).getASuccessor() = out and - subpaths03(arg, p, localStepToHidden*(ret), o, apout) and + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) { + exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and + subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and + hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and - par.getNodeEx() = p and - out.getNodeEx() = o and - out.getAp() = apout + pathNode(out0, o, sout, _, _, apout, _, _) + | + out = out0 or out = out0.projectToSink() ) } /** - * Holds if `n` can reach a return node in a summarized subpath. + * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { - subpaths(_, _, n, _) + predicate retReach(PathNodeImpl n) { + exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } @@ -3867,12 +3884,22 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( - PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration + PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, + Configuration configuration ) { flowsource.isSource() and flowsource.getConfiguration() = configuration and - flowsource.(PathNodeImpl).getNodeEx().asNode() = source and + flowsource.getNodeEx().asNode() = source and (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and flowsink.getNodeEx().asNode() = sink } @@ -3887,18 +3914,22 @@ predicate flowsTo(Node source, Node sink, Configuration configuration) { flowsTo(_, _, source, sink, configuration) } -private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, int tuples) { +private predicate finalStats( + boolean fwd, int nodes, int fields, int conscand, int states, int tuples +) { fwd = true and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0)) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and - tuples = count(PathNode pn) + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and + tuples = count(PathNodeImpl pn) or fwd = false and nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and - tuples = count(PathNode pn | reach(pn)) + states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and + tuples = count(PathNode pn) } /** @@ -3907,27 +3938,52 @@ private predicate finalStats(boolean fwd, int nodes, int fields, int conscand, i * Calculates per-stage metrics for data flow. */ predicate stageStats( - int n, string stage, int nodes, int fields, int conscand, int tuples, Configuration config + int n, string stage, int nodes, int fields, int conscand, int states, int tuples, + Configuration config ) { - stage = "1 Fwd" and n = 10 and Stage1::stats(true, nodes, fields, conscand, tuples, config) + stage = "1 Fwd" and + n = 10 and + Stage1::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "1 Rev" and n = 15 and Stage1::stats(false, nodes, fields, conscand, tuples, config) + stage = "1 Rev" and + n = 15 and + Stage1::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "2 Fwd" and n = 20 and Stage2::stats(true, nodes, fields, conscand, tuples, config) + stage = "2 Fwd" and + n = 20 and + Stage2::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "2 Rev" and n = 25 and Stage2::stats(false, nodes, fields, conscand, tuples, config) + stage = "2 Rev" and + n = 25 and + Stage2::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "3 Fwd" and n = 30 and Stage3::stats(true, nodes, fields, conscand, tuples, config) + stage = "3 Fwd" and + n = 30 and + Stage3::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "3 Rev" and n = 35 and Stage3::stats(false, nodes, fields, conscand, tuples, config) + stage = "3 Rev" and + n = 35 and + Stage3::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "4 Fwd" and n = 40 and Stage4::stats(true, nodes, fields, conscand, tuples, config) + stage = "4 Fwd" and + n = 40 and + Stage4::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "4 Rev" and n = 45 and Stage4::stats(false, nodes, fields, conscand, tuples, config) + stage = "4 Rev" and + n = 45 and + Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { @@ -3937,6 +3993,8 @@ private module FlowExploration { or additionalJumpStep(node1, node2, config) or + additionalJumpStateStep(node1, _, node2, _, config) + or // flow into callable viableParamArgEx(_, node2, node1) or @@ -3950,7 +4008,7 @@ private module FlowExploration { } private predicate interestingCallableSrc(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSource(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSource(n) or config.isSource(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSrc(mid, config) and callableStep(mid, c, config) @@ -3958,7 +4016,7 @@ private module FlowExploration { } private predicate interestingCallableSink(DataFlowCallable c, Configuration config) { - exists(Node n | config.isSink(n) and c = getNodeEnclosingCallable(n)) + exists(Node n | config.isSink(n) or config.isSink(n, _) | c = getNodeEnclosingCallable(n)) or exists(DataFlowCallable mid | interestingCallableSink(mid, config) and callableStep(c, mid, config) @@ -3986,13 +4044,13 @@ private module FlowExploration { or exists(Node n, Configuration config | ce1 = TCallableSrc() and - config.isSource(n) and + (config.isSource(n) or config.isSource(n, _)) and ce2 = TCallable(getNodeEnclosingCallable(n), config) ) or exists(Node n, Configuration config | ce2 = TCallableSink() and - config.isSink(n) and + (config.isSink(n) or config.isSink(n, _)) and ce1 = TCallable(getNodeEnclosingCallable(n), config) ) } @@ -4094,13 +4152,26 @@ private module FlowExploration { } } + private predicate relevantState(FlowState state) { + sourceNode(_, state, _) or + sinkNode(_, state, _) or + additionalLocalStateStep(_, state, _, _, _) or + additionalLocalStateStep(_, _, _, state, _) or + additionalJumpStateStep(_, state, _, _, _) or + additionalJumpStateStep(_, _, _, state, _) + } + private newtype TSummaryCtx1 = TSummaryCtx1None() or TSummaryCtx1Param(ParamNodeEx p) private newtype TSummaryCtx2 = TSummaryCtx2None() or - TSummaryCtx2Some(PartialAccessPath ap) + TSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TSummaryCtx3 = + TSummaryCtx3None() or + TSummaryCtx3Some(PartialAccessPath ap) private newtype TRevSummaryCtx1 = TRevSummaryCtx1None() or @@ -4108,52 +4179,66 @@ private module FlowExploration { private newtype TRevSummaryCtx2 = TRevSummaryCtx2None() or - TRevSummaryCtx2Some(RevPartialAccessPath ap) + TRevSummaryCtx2Some(FlowState s) { relevantState(s) } + + private newtype TRevSummaryCtx3 = + TRevSummaryCtx3None() or + TRevSummaryCtx3Some(RevPartialAccessPath ap) private newtype TPartialPathNode = TPartialPathNodeFwd( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = TPartialNil(node.getDataFlowType()) and - not fullBarrier(node, config) and exists(config.explorationLimit()) or - partialPathNodeMk0(node, cc, sc1, sc2, ap, config) and + partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, ap, config) and distSrc(node.getEnclosingCallable(), config) <= config.explorationLimit() } or TPartialPathNodeRev( - NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, RevPartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, TRevSummaryCtx3 sc3, + RevPartialAccessPath ap, Configuration config ) { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() and - not fullBarrier(node, config) and exists(config.explorationLimit()) or exists(PartialPathNodeRev mid | - revPartialPathStep(mid, node, sc1, sc2, ap, config) and - not clearsContentCached(node.asNode(), ap.getHead()) and + revPartialPathStep(mid, node, state, sc1, sc2, sc3, ap, config) and + not clearsContentEx(node, ap.getHead()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead()) + ) and not fullBarrier(node, config) and + not stateBarrier(node, state, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) } pragma[nomagic] private predicate partialPathNodeMk0( - NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialAccessPath ap, - Configuration config + NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid | - partialPathStep(mid, node, cc, sc1, sc2, ap, config) and + partialPathStep(mid, node, state, cc, sc1, sc2, sc3, ap, config) and not fullBarrier(node, config) and - not clearsContentCached(node.asNode(), ap.getHead().getContent()) and + not stateBarrier(node, state, config) and + not clearsContentEx(node, ap.getHead().getContent()) and + ( + notExpectsContent(node) or + expectsContentEx(node, ap.getHead().getContent()) + ) and if node.asNode() instanceof CastingNode then compatibleTypes(node.getDataFlowType(), ap.getType()) else any() @@ -4191,6 +4276,8 @@ private module FlowExploration { /** Gets the underlying `Node`. */ final Node getNode() { this.getNodeEx().projectToNode() = result } + FlowState getState() { none() } + private NodeEx getNodeEx() { result = this.(PartialPathNodeFwd).getNodeEx() or result = this.(PartialPathNodeRev).getNodeEx() @@ -4248,135 +4335,182 @@ private module FlowExploration { private class PartialPathNodeFwd extends PartialPathNode, TPartialPathNodeFwd { NodeEx node; + FlowState state; CallContext cc; TSummaryCtx1 sc1; TSummaryCtx2 sc2; + TSummaryCtx3 sc3; PartialAccessPath ap; Configuration config; - PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, cc, sc1, sc2, ap, config) } + PartialPathNodeFwd() { this = TPartialPathNodeFwd(node, state, cc, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + CallContext getCallContext() { result = cc } TSummaryCtx1 getSummaryCtx1() { result = sc1 } TSummaryCtx2 getSummaryCtx2() { result = sc2 } + TSummaryCtx3 getSummaryCtx3() { result = sc3 } + PartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeFwd getASuccessor() { - partialPathStep(this, result.getNodeEx(), result.getCallContext(), result.getSummaryCtx1(), - result.getSummaryCtx2(), result.getAp(), result.getConfiguration()) + partialPathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), + result.getSummaryCtx1(), result.getSummaryCtx2(), result.getSummaryCtx3(), result.getAp(), + result.getConfiguration()) } predicate isSource() { - sourceNode(node, config) and + sourceNode(node, state, config) and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap instanceof TPartialNil } } private class PartialPathNodeRev extends PartialPathNode, TPartialPathNodeRev { NodeEx node; + FlowState state; TRevSummaryCtx1 sc1; TRevSummaryCtx2 sc2; + TRevSummaryCtx3 sc3; RevPartialAccessPath ap; Configuration config; - PartialPathNodeRev() { this = TPartialPathNodeRev(node, sc1, sc2, ap, config) } + PartialPathNodeRev() { this = TPartialPathNodeRev(node, state, sc1, sc2, sc3, ap, config) } NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + TRevSummaryCtx1 getSummaryCtx1() { result = sc1 } TRevSummaryCtx2 getSummaryCtx2() { result = sc2 } + TRevSummaryCtx3 getSummaryCtx3() { result = sc3 } + RevPartialAccessPath getAp() { result = ap } override Configuration getConfiguration() { result = config } override PartialPathNodeRev getASuccessor() { - revPartialPathStep(result, this.getNodeEx(), this.getSummaryCtx1(), this.getSummaryCtx2(), - this.getAp(), this.getConfiguration()) + revPartialPathStep(result, this.getNodeEx(), this.getState(), this.getSummaryCtx1(), + this.getSummaryCtx2(), this.getSummaryCtx3(), this.getAp(), this.getConfiguration()) } predicate isSink() { - sinkNode(node, config) and + sinkNode(node, state, config) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = TRevPartialNil() } } private predicate partialPathStep( - PartialPathNodeFwd mid, NodeEx node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { not isUnreachableInCallCached(node.asNode(), cc.(CallContextSpecificCall).getCall()) and ( localFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc = mid.getCallContext() and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() ) or jumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(mid.getNodeEx(), node, config) and + state = mid.getState() and cc instanceof CallContextAny and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and + mid.getAp() instanceof PartialAccessPathNil and + ap = TPartialNil(node.getDataFlowType()) and + config = mid.getConfiguration() + or + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, config) and + cc instanceof CallContextAny and + sc1 = TSummaryCtx1None() and + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() and mid.getAp() instanceof PartialAccessPathNil and ap = TPartialNil(node.getDataFlowType()) and config = mid.getConfiguration() or partialPathStoreStep(mid, _, _, node, ap) and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(PartialAccessPath ap0, TypedContent tc | partialPathReadStep(mid, ap0, tc, node, cc, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsFwd(ap, tc, ap0, config) ) or - partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config) + partialPathIntoCallable(mid, node, state, _, cc, sc1, sc2, sc3, _, ap, config) or - partialPathOutOfCallable(mid, node, cc, ap, config) and + partialPathOutOfCallable(mid, node, state, cc, ap, config) and sc1 = TSummaryCtx1None() and - sc2 = TSummaryCtx2None() + sc2 = TSummaryCtx2None() and + sc3 = TSummaryCtx3None() or - partialPathThroughCallable(mid, node, cc, ap, config) and + partialPathThroughCallable(mid, node, state, cc, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } bindingset[result, i] - private int unbindInt(int i) { i <= result and i >= result } + private int unbindInt(int i) { pragma[only_bind_out](i) = pragma[only_bind_out](result) } pragma[inline] private predicate partialPathStoreStep( @@ -4419,10 +4553,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable0( - PartialPathNodeFwd mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, + PartialAccessPath ap, Configuration config ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and + state = mid.getState() and innercc = mid.getCallContext() and innercc instanceof CallContextNoCall and ap = mid.getAp() and @@ -4431,11 +4566,11 @@ private module FlowExploration { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, CallContext cc, + PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - partialPathOutOfCallable0(mid, pos, innercc, ap, config) and + partialPathOutOfCallable0(mid, pos, state, innercc, ap, config) and c = pos.getCallable() and kind = pos.getKind() and resolveReturn(innercc, c, call) @@ -4445,10 +4580,11 @@ private module FlowExploration { } private predicate partialPathOutOfCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(ReturnKindExt kind, DataFlowCall call | - partialPathOutOfCallable1(mid, call, kind, cc, ap, config) + partialPathOutOfCallable1(mid, call, kind, state, cc, ap, config) | out.asNode() = kind.getAnOutNode(call) ) @@ -4456,37 +4592,40 @@ private module FlowExploration { pragma[noinline] private predicate partialPathIntoArg( - PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(ArgNode arg | + exists(ArgNode arg, ArgumentPosition apos | arg = mid.getNodeEx().asNode() and + state = mid.getState() and cc = mid.getCallContext() and - arg.argumentOf(call, i) and + arg.argumentOf(call, apos) and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate partialPathIntoCallable0( - PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc, - DataFlowCall call, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, + CallContext outercc, DataFlowCall call, PartialAccessPath ap, Configuration config ) { - partialPathIntoArg(mid, i, outercc, call, ap, config) and + partialPathIntoArg(mid, pos, state, outercc, call, ap, config) and callable = resolveCall(call, outercc) } private predicate partialPathIntoCallable( - PartialPathNodeFwd mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, - TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap, - Configuration config + PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, + CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, + DataFlowCall call, PartialAccessPath ap, Configuration config ) { - exists(int i, DataFlowCallable callable | - partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and - p.isParameterOf(callable, i) and + exists(ParameterPosition pos, DataFlowCallable callable | + partialPathIntoCallable0(mid, callable, pos, state, outercc, call, ap, config) and + p.isParameterOf(callable, pos) and sc1 = TSummaryCtx1Param(p) and - sc2 = TSummaryCtx2Some(ap) + sc2 = TSummaryCtx2Some(state) and + sc3 = TSummaryCtx3Some(ap) | if recordDataFlowCallSite(call, callable) then innercc = TSpecificCall(call) @@ -4496,15 +4635,17 @@ private module FlowExploration { pragma[nomagic] private predicate paramFlowsThroughInPartialPath( - ReturnKindExt kind, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - PartialAccessPath ap, Configuration config + ReturnKindExt kind, FlowState state, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, + TSummaryCtx3 sc3, PartialAccessPath ap, Configuration config ) { exists(PartialPathNodeFwd mid, RetNodeEx ret | mid.getNodeEx() = ret and kind = ret.getKind() and + state = mid.getState() and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() and ap = mid.getAp() ) @@ -4512,85 +4653,119 @@ private module FlowExploration { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc, + DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, PartialAccessPath ap, Configuration config ) { - exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 | - partialPathIntoCallable(mid, _, cc, innercc, sc1, sc2, call, _, config) and - paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config) + exists(CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3 | + partialPathIntoCallable(mid, _, _, cc, innercc, sc1, sc2, sc3, call, _, config) and + paramFlowsThroughInPartialPath(kind, state, innercc, sc1, sc2, sc3, ap, config) ) } private predicate partialPathThroughCallable( - PartialPathNodeFwd mid, NodeEx out, CallContext cc, PartialAccessPath ap, Configuration config + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, PartialAccessPath ap, + Configuration config ) { exists(DataFlowCall call, ReturnKindExt kind | - partialPathThroughCallable0(call, mid, kind, cc, ap, config) and + partialPathThroughCallable0(call, mid, kind, state, cc, ap, config) and out.asNode() = kind.getAnOutNode(call) ) } + pragma[nomagic] private predicate revPartialPathStep( - PartialPathNodeRev mid, NodeEx node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, - RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, NodeEx node, FlowState state, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, + TRevSummaryCtx3 sc3, RevPartialAccessPath ap, Configuration config ) { localFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and config = mid.getConfiguration() or additionalLocalFlowStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = mid.getSummaryCtx1() and + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or jumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() or additionalJumpStep(node, mid.getNodeEx(), config) and + state = mid.getState() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and + mid.getAp() instanceof RevPartialAccessPathNil and + ap = TRevPartialNil() and + config = mid.getConfiguration() + or + additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState(), config) and + sc1 = TRevSummaryCtx1None() and + sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and mid.getAp() instanceof RevPartialAccessPathNil and ap = TRevPartialNil() and config = mid.getConfiguration() or revPartialPathReadStep(mid, _, _, node, ap) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and config = mid.getConfiguration() or exists(RevPartialAccessPath ap0, Content c | revPartialPathStoreStep(mid, ap0, c, node, config) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and apConsRev(ap, c, ap0, config) ) or exists(ParamNodeEx p | mid.getNodeEx() = p and viableParamArgEx(_, p, node) and + state = mid.getState() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and + sc3 = TRevSummaryCtx3None() and ap = mid.getAp() and config = mid.getConfiguration() ) or exists(ReturnPosition pos | - revPartialPathIntoReturn(mid, pos, sc1, sc2, _, ap, config) and + revPartialPathIntoReturn(mid, pos, state, sc1, sc2, sc3, _, ap, config) and pos = getReturnPosition(node.asNode()) ) or - revPartialPathThroughCallable(mid, node, ap, config) and + revPartialPathThroughCallable(mid, node, state, ap, config) and sc1 = mid.getSummaryCtx1() and - sc2 = mid.getSummaryCtx2() + sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() } pragma[inline] @@ -4633,14 +4808,17 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathIntoReturn( - PartialPathNodeRev mid, ReturnPosition pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, - DataFlowCall call, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, RevPartialAccessPath ap, + Configuration config ) { exists(NodeEx out | mid.getNodeEx() = out and + mid.getState() = state and viableReturnPosOutEx(call, pos, out) and sc1 = TRevSummaryCtx1Some(pos) and - sc2 = TRevSummaryCtx2Some(ap) and + sc2 = TRevSummaryCtx2Some(state) and + sc3 = TRevSummaryCtx3Some(ap) and ap = mid.getAp() and config = mid.getConfiguration() ) @@ -4648,36 +4826,40 @@ private module FlowExploration { pragma[nomagic] private predicate revPartialPathFlowsThrough( - int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap, - Configuration config + ArgumentPosition apos, FlowState state, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, + TRevSummaryCtx3Some sc3, RevPartialAccessPath ap, Configuration config ) { - exists(PartialPathNodeRev mid, ParamNodeEx p | + exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos | mid.getNodeEx() = p and - p.getPosition() = pos and + mid.getState() = state and + p.getPosition() = ppos and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and + sc3 = mid.getSummaryCtx3() and ap = mid.getAp() and - config = mid.getConfiguration() + config = mid.getConfiguration() and + parameterMatch(ppos, apos) ) } pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap, - Configuration config + DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, + RevPartialAccessPath ap, Configuration config ) { - exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 | - revPartialPathIntoReturn(mid, _, sc1, sc2, call, _, config) and - revPartialPathFlowsThrough(pos, sc1, sc2, ap, config) + exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | + revPartialPathIntoReturn(mid, _, _, sc1, sc2, sc3, call, _, config) and + revPartialPathFlowsThrough(pos, state, sc1, sc2, sc3, ap, config) ) } pragma[nomagic] private predicate revPartialPathThroughCallable( - PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config + PartialPathNodeRev mid, ArgNodeEx node, FlowState state, RevPartialAccessPath ap, + Configuration config ) { - exists(DataFlowCall call, int pos | - revPartialPathThroughCallable0(call, mid, pos, ap, config) and + exists(DataFlowCall call, ArgumentPosition pos | + revPartialPathThroughCallable0(call, mid, pos, state, ap, config) and node.asNode().(ArgNode).argumentOf(call, pos) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index c139593b1b8..9aa6a529a5b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -3,6 +3,17 @@ private import DataFlowImplSpecific::Public import Cached module DataFlowImplCommonPublic { + /** A state value to track during data flow. */ + class FlowState = string; + + /** + * The default state, which is used when the state is unspecified for a source + * or a sink. + */ + class FlowStateEmpty extends FlowState { + FlowStateEmpty() { this = "" } + } + private newtype TFlowFeature = TFeatureHasSourceCallContext() or TFeatureHasSinkCallContext() or @@ -62,6 +73,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { tupleLimit = 1000 } +/** + * Holds if `arg` is an argument of `call` with an argument position that matches + * parameter position `ppos`. + */ +pragma[noinline] +predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) { + exists(ArgumentPosition apos | + arg.argumentOf(call, apos) and + parameterMatch(ppos, apos) + ) +} + /** * Provides a simple data-flow analysis for resolving lambda calls. The analysis * currently excludes read-steps, store-steps, and flow-through. @@ -71,25 +94,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { * calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly. */ private module LambdaFlow { - private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallable(call), i) + pragma[noinline] + private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallable(call), ppos) } - private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallableLambda(call, _), i) + pragma[noinline] + private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallableLambda(call, _), ppos) } private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParamNonLambda(call, i, p) and - arg.argumentOf(call, i) + exists(ParameterPosition ppos | + viableParamNonLambda(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) ) } private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParamLambda(call, i, p) and - arg.argumentOf(call, i) + exists(ParameterPosition ppos | + viableParamLambda(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) ) } @@ -191,10 +216,9 @@ private module LambdaFlow { or // jump step exists(Node mid, DataFlowType t0 | - revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and + revLambdaFlow(lambdaCall, kind, mid, t0, _, _, lastCall) and toReturn = false and - toJump = true and - lastCall = TDataFlowCallNone() + toJump = true | jumpStepCached(node, mid) and t = t0 @@ -301,7 +325,10 @@ private module Cached { predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) } cached - predicate clearsContentCached(Node n, Content c) { clearsContent(n, c) } + predicate clearsContentCached(Node n, ContentSet c) { clearsContent(n, c) } + + cached + predicate expectsContentCached(Node n, ContentSet c) { expectsContent(n, c) } cached predicate isUnreachableInCallCached(Node n, DataFlowCall call) { isUnreachableInCall(n, call) } @@ -322,7 +349,7 @@ private module Cached { or exists(ArgNode arg | result.(PostUpdateNode).getPreUpdateNode() = arg and - arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition()) + arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) ) } @@ -330,7 +357,7 @@ private module Cached { predicate returnNodeExt(Node n, ReturnKindExt k) { k = TValueReturn(n.(ReturnNode).getKind()) or - exists(ParamNode p, int pos | + exists(ParamNode p, ParameterPosition pos | parameterValueFlowsToPreUpdate(p, n) and p.isParameterOf(_, pos) and k = TParamUpdate(pos) @@ -348,15 +375,17 @@ private module Cached { // For reads, `x.f`, we want to check that the tracked type after the read (which // is obtained by popping the head of the access path stack) is compatible with // the type of `x.f`. - read(_, _, n) + readSet(_, _, n) } cached - predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) } + predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) { + isParameterNode(p, c, pos) + } cached - predicate argumentNode(Node n, DataFlowCall call, int pos) { - n.(ArgumentNode).argumentOf(call, pos) + predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) { + isArgumentNode(n, call, pos) } /** @@ -374,12 +403,12 @@ private module Cached { } /** - * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. - * The instance parameter is considered to have index `-1`. + * Holds if `p` is the parameter of a viable dispatch target of `call`, + * and `p` has position `ppos`. */ pragma[nomagic] - private predicate viableParam(DataFlowCall call, int i, ParamNode p) { - p.isParameterOf(viableCallableExt(call), i) + private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + p.isParameterOf(viableCallableExt(call), ppos) } /** @@ -388,9 +417,9 @@ private module Cached { */ cached predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) { - exists(int i | - viableParam(call, i, p) and - arg.argumentOf(call, i) and + exists(ParameterPosition ppos | + viableParam(call, ppos, p) and + argumentPositionMatch(call, arg, ppos) and compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) ) } @@ -442,7 +471,7 @@ private module Cached { // read exists(Node mid | parameterValueFlowCand(p, mid, false) and - read(mid, _, node) and + readSet(mid, _, node) and read = true ) or @@ -630,8 +659,10 @@ private module Cached { * Holds if `arg` flows to `out` through a call using only * value-preserving steps and a single read step, not taking call * contexts into account, thus representing a getter-step. + * + * This predicate is exposed for testing only. */ - predicate getterStep(ArgNode arg, Content c, Node out) { + predicate getterStep(ArgNode arg, ContentSet c, Node out) { argumentValueFlowsThrough(arg, TReadStepTypesSome(_, c, _), out) } @@ -678,7 +709,8 @@ private module Cached { */ pragma[nomagic] private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) + result = viableImplInCallContext(call, ctx) and + result = viableCallable(call) or result = viableCallableLambda(call, TDataFlowCallSome(ctx)) or @@ -754,8 +786,12 @@ private module Cached { parameterValueFlow(p, n.getPreUpdateNode(), TReadStepTypesNone()) } - private predicate store( - Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType + cached + predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) } + + cached + predicate storeSet( + Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType ) { storeStep(node1, c, node2) and contentType = getNodeDataFlowType(node1) and @@ -767,14 +803,19 @@ private module Cached { | argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1) or - read(n2, c, n1) and + readSet(n2, c, n1) and contentType = getNodeDataFlowType(n1) and containerType = getNodeDataFlowType(n2) ) } - cached - predicate read(Node node1, Content c, Node node2) { readStep(node1, c, node2) } + private predicate store( + Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType + ) { + exists(ContentSet cs | + c = cs.getAStoreContent() and storeSet(node1, cs, node2, contentType, containerType) + ) + } /** * Holds if data can flow from `node1` to `node2` via a direct assignment to @@ -862,7 +903,7 @@ private module Cached { cached newtype TReturnKindExt = TValueReturn(ReturnKind kind) or - TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) } + TParamUpdate(ParameterPosition pos) { exists(ParamNode p | p.isParameterOf(_, pos)) } cached newtype TBooleanOption = @@ -874,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -905,16 +985,16 @@ class CastingNode extends Node { } private predicate readStepWithTypes( - Node n1, DataFlowType container, Content c, Node n2, DataFlowType content + Node n1, DataFlowType container, ContentSet c, Node n2, DataFlowType content ) { - read(n1, c, n2) and + readSet(n1, c, n2) and container = getNodeDataFlowType(n1) and content = getNodeDataFlowType(n2) } private newtype TReadStepTypesOption = TReadStepTypesNone() or - TReadStepTypesSome(DataFlowType container, Content c, DataFlowType content) { + TReadStepTypesSome(DataFlowType container, ContentSet c, DataFlowType content) { readStepWithTypes(_, container, c, _, content) } @@ -923,7 +1003,7 @@ private class ReadStepTypesOption extends TReadStepTypesOption { DataFlowType getContainerType() { this = TReadStepTypesSome(result, _, _) } - Content getContent() { this = TReadStepTypesSome(_, result, _) } + ContentSet getContent() { this = TReadStepTypesSome(_, result, _) } DataFlowType getContentType() { this = TReadStepTypesSome(_, _, result) } @@ -1054,9 +1134,9 @@ class ParamNode extends Node { /** * Holds if this node is the parameter of callable `c` at the specified - * (zero-based) position. + * position. */ - predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) } + predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameterNode(this, c, pos) } } /** A data-flow node that represents a call argument. */ @@ -1064,7 +1144,9 @@ class ArgNode extends Node { ArgNode() { argumentNode(this, _, _) } /** Holds if this argument occurs at the given position in the given call. */ - final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) } + final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + argumentNode(this, call, pos) + } } /** @@ -1110,11 +1192,14 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn { } class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate { - private int pos; + private ParameterPosition pos; ParamUpdateReturnKind() { this = TParamUpdate(pos) } - int getPosition() { result = pos } + ParameterPosition getPosition() { result = pos } + + pragma[nomagic] + ArgumentPosition getAMatchingArgumentPosition() { parameterMatch(pos, result) } override string toString() { result = "param update " + pos } } @@ -1258,7 +1343,114 @@ class DataFlowCallOption extends TDataFlowCallOption { } } -/** Content tagged with the type of a containing object. */ +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + +/** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; private DataFlowType t; @@ -1290,11 +1482,9 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } - - predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) } } class AccessPathFrontNil extends AccessPathFront, TFrontNil { @@ -1306,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1318,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index ea3f757b440..715330f87d9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -12,7 +12,7 @@ private newtype TNode = MkGlobalFunctionNode(Function f) or MkSummarizedParameterNode(DataFlowCallable c, int i) { not exists(c.getFuncDef()) and - c instanceof SummarizedCallable and + c.asCallable() instanceof SummarizedCallable and ( i in [0 .. c.getType().getNumParameter() - 1] or @@ -25,6 +25,8 @@ private newtype TNode = /** Nodes intended for only use inside the data-flow libraries. */ module Private { + private import DataFlowDispatch + /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result.asCallable() = n.getEnclosingCallable() @@ -33,10 +35,15 @@ module Private { } /** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */ - predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { + predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { p.isParameterOf(c.asCallable(), pos) } + /** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */ + predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) { + arg.argumentOf(c, pos) + } + /** A data flow node that represents returning a value from a function. */ class ReturnNode extends Node { ReturnKind kind; @@ -115,7 +122,7 @@ module Public { exists(DataFlowCallable dfc | result = dfc.asCallable() | this = MkSummarizedParameterNode(dfc, _) or - this = MkSummaryInternalNode(dfc, _) + this = MkSummaryInternalNode(dfc.asCallable(), _) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index d83014b0b93..b65fb3d7d5d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -126,6 +126,8 @@ predicate jumpStep(Node n1, Node n2) { n1.(DataFlow::PostUpdateNode).getPreUpdateNode() = sendRead and n2 = recvRead ) + or + FlowSummaryImpl::Private::Steps::summaryJumpStep(n1, n2) } /** @@ -188,22 +190,26 @@ predicate clearsContent(Node n, Content c) { // FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) } -/** Gets the type of `n` used for type pruning. */ -DataFlowType getNodeType(Node n) { - result = n.getType() - or - result = FlowSummaryImpl::Private::summaryNodeType(n) +/** + * Holds if the value that is being tracked is expected to be stored inside content `c` + * at node `n`. + */ +predicate expectsContent(Node n, ContentSet c) { + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) } +/** Gets the type of `n` used for type pruning. */ +DataFlowType getNodeType(Node n) { result = TTodoDataFlowType() and exists(n) } + /** Gets a string representation of a type returned by `getNodeType()`. */ -string ppReprType(Type t) { result = t.toString() } +string ppReprType(DataFlowType t) { none() } /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. */ pragma[inline] -predicate compatibleTypes(Type t1, Type t2) { +predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() // stub implementation } @@ -217,7 +223,14 @@ class CastNode extends ExprNode { class DataFlowExpr = Expr; -class DataFlowType = Type; +private newtype TDataFlowType = + TTodoDataFlowType() or + TTodoDataFlowType2() // Add a dummy value to prevent bad functionality-induced joins arising from a type of size 1. + +class DataFlowType extends TDataFlowType { + /** Gets a textual representation of this element. */ + string toString() { result = "" } +} class DataFlowLocation = Location; @@ -370,3 +383,10 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves predicate allowParameterReturnInSelf(ParameterNode p) { FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) } + +/** An approximated `Content`. */ +class ContentApprox = Unit; + +/** Gets an approximated value for content `c`. */ +pragma[inline] +ContentApprox getContentApprox(Content c) { any() } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index d0a92a322c0..a604f1b875b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -108,7 +108,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _) } /** @@ -131,6 +131,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { * Holds if data flows from `source` to `sink` in zero or more local * (intra-procedural) steps. */ +pragma[inline] predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } private newtype TContent = @@ -148,7 +149,7 @@ private newtype TContent = */ class Content extends TContent { /** Gets the type of the contained data for the purpose of type pruning. */ - DataFlowType getType() { result instanceof EmptyInterfaceType } + DataFlowType getType() { any() } /** Gets a textual representation of this element. */ abstract string toString(); @@ -160,8 +161,10 @@ class Content extends TContent { * For more information, see * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 } } @@ -174,7 +177,7 @@ class FieldContent extends Content, TFieldContent { /** Gets the field associated with this `FieldContent`. */ Field getField() { result = f } - override DataFlowType getType() { result = f.getType() } + override DataFlowType getType() { any() } override string toString() { result = f.toString() } @@ -202,7 +205,7 @@ class PointerContent extends Content, TPointerContent { /** Gets the pointer type that containers with this content must have. */ PointerType getPointerType() { result = t } - override DataFlowType getType() { result = t.getBaseType() } + override DataFlowType getType() { any() } override string toString() { result = "pointer" } } @@ -225,11 +228,41 @@ class SyntheticFieldContent extends Content, TSyntheticFieldContent { /** Gets the field associated with this `SyntheticFieldContent`. */ SyntheticField getField() { result = s } - override DataFlowType getType() { result = s.getType() } + override DataFlowType getType() { any() } override string toString() { result = s.toString() } } +/** + * An entity that represents a set of `Content`s. + * + * The set may be interpreted differently depending on whether it is + * stored into (`getAStoreContent`) or read from (`getAReadContent`). + */ +class ContentSet instanceof Content { + /** Gets a content that may be stored into when storing into this set. */ + Content getAStoreContent() { result = this } + + /** Gets a content that may be read from when reading from this set. */ + Content getAReadContent() { result = this } + + /** Gets a textual representation of this content set. */ + string toString() { result = super.toString() } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } +} + /** * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`. * diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index e59c96a5c17..b61142c33a7 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -24,7 +24,11 @@ module Public { class SummaryComponent extends TSummaryComponent { /** Gets a textual representation of this summary component. */ string toString() { - exists(Content c | this = TContentSummaryComponent(c) and result = c.toString()) + exists(ContentSet c | this = TContentSummaryComponent(c) and result = c.toString()) + or + exists(ContentSet c | this = TWithoutContentSummaryComponent(c) and result = "without " + c) + or + exists(ContentSet c | this = TWithContentSummaryComponent(c) and result = "with " + c) or exists(ArgumentPosition pos | this = TParameterSummaryComponent(pos) and result = "parameter " + pos @@ -41,7 +45,13 @@ module Public { /** Provides predicates for constructing summary components. */ module SummaryComponent { /** Gets a summary component for content `c`. */ - SummaryComponent content(Content c) { result = TContentSummaryComponent(c) } + SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) } + + /** Gets a summary component where data is not allowed to be stored in `c`. */ + SummaryComponent withoutContent(ContentSet c) { result = TWithoutContentSummaryComponent(c) } + + /** Gets a summary component where data must be stored in `c`. */ + SummaryComponent withContent(ContentSet c) { result = TWithContentSummaryComponent(c) } /** Gets a summary component for a parameter at position `pos`. */ SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) } @@ -51,6 +61,20 @@ module Public { /** Gets a summary component for a return of kind `rk`. */ SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) } + + /** Gets a summary component for synthetic global `sg`. */ + SummaryComponent syntheticGlobal(SyntheticGlobal sg) { + result = TSyntheticGlobalSummaryComponent(sg) + } + + /** + * A synthetic global. This represents some form of global state, which + * summaries can read and write individually. + */ + abstract class SyntheticGlobal extends string { + bindingset[this] + SyntheticGlobal() { any() } + } } /** @@ -185,7 +209,10 @@ module Public { } /** A callable with a flow summary. */ - abstract class SummarizedCallable extends DataFlowCallable { + abstract class SummarizedCallable extends SummarizedCallableBase { + bindingset[this] + SummarizedCallable() { any() } + /** * Holds if data may flow from `input` to `output` through this callable. * @@ -214,11 +241,25 @@ module Public { } /** - * Holds if values stored inside `content` are cleared on objects passed as - * arguments at position `pos` to this callable. + * Holds if the summary is auto generated and not manually generated. */ - pragma[nomagic] - predicate clearsContent(ParameterPosition pos, Content content) { none() } + predicate isAutoGenerated() { none() } + + /** + * Holds if the summary has the given provenance where `true` is + * `generated` and `false` is `manual`. + */ + predicate hasProvenance(boolean generated) { none() } + } + + /** A callable where there is no flow via the callable. */ + class NeutralCallable extends SummarizedCallableBase { + NeutralCallable() { neutralElement(this, _) } + + /** + * Holds if the neutral is auto generated. + */ + predicate isAutoGenerated() { neutralElement(this, true) } } } @@ -231,10 +272,13 @@ module Private { import AccessPathSyntax newtype TSummaryComponent = - TContentSummaryComponent(Content c) or + TContentSummaryComponent(ContentSet c) or TParameterSummaryComponent(ArgumentPosition pos) or TArgumentSummaryComponent(ParameterPosition pos) or - TReturnSummaryComponent(ReturnKind rk) + TReturnSummaryComponent(ReturnKind rk) or + TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or + TWithoutContentSummaryComponent(ContentSet c) or + TWithContentSummaryComponent(ContentSet c) private TParameterSummaryComponent thisParam() { result = TParameterSummaryComponent(instanceParameterPosition()) @@ -378,10 +422,7 @@ module Private { private newtype TSummaryNodeState = TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or - TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or - TSummaryNodeClearsContentState(ParameterPosition pos, boolean post) { - any(SummarizedCallable sc).clearsContent(pos, _) and post in [false, true] - } + TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } /** * A state used to break up (complex) flow summaries into atomic flow steps. @@ -428,12 +469,6 @@ module Private { this = TSummaryNodeOutputState(s) and result = "to write: " + s ) - or - exists(ParameterPosition pos, boolean post, string postStr | - this = TSummaryNodeClearsContentState(pos, post) and - (if post = true then postStr = " (post)" else postStr = "") and - result = "clear: " + pos + postStr - ) } } @@ -457,11 +492,6 @@ module Private { not parameterReadState(c, state, _) or state.isOutputState(c, _) - or - exists(ParameterPosition pos | - c.clearsContent(pos, _) and - state = TSummaryNodeClearsContentState(pos, _) - ) } pragma[noinline] @@ -471,7 +501,7 @@ module Private { or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(c, pos) + result.(ParamNode).isParameterOf(inject(c), pos) ) ) } @@ -496,9 +526,8 @@ module Private { predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or - isParameterPostUpdate(_, c, pos) - or - c.clearsContent(pos, _) + // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context + any(SummaryNodeState state).isOutputState(c, SummaryComponentStack::argument(pos)) } private predicate callbackOutput( @@ -506,7 +535,7 @@ module Private { ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and - receiver = summaryNodeInputState(c, s.drop(1)) + receiver = summaryNodeInputState(c, s.tail()) } private predicate callbackInput( @@ -514,7 +543,7 @@ module Private { ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and - receiver = summaryNodeInputState(c, s.drop(1)) + receiver = summaryNodeInputState(c, s.tail()) } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ @@ -540,21 +569,32 @@ module Private { exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | n = summaryNodeInputState(c, s) and ( - exists(Content cont | - head = TContentSummaryComponent(cont) and result = getContentType(cont) + exists(ContentSet cont | result = getContentType(cont) | + head = TContentSummaryComponent(cont) or + head = TWithContentSummaryComponent(cont) + ) + or + exists(ContentSet cont | + head = TWithoutContentSummaryComponent(cont) and + result = getNodeType(summaryNodeInputState(c, s.tail())) ) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.drop(1))), rk) + s.tail())), rk) + ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) ) ) or n = summaryNodeOutputState(c, s) and ( - exists(Content cont | + exists(ContentSet cont | head = TContentSummaryComponent(cont) and result = getContentType(cont) ) or @@ -567,16 +607,15 @@ module Private { exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), - s.drop(1))), pos) + s.tail())), pos) + ) + or + exists(SummaryComponent::SyntheticGlobal sg | + head = TSyntheticGlobalSummaryComponent(sg) and + result = getSyntheticGlobalType(sg) ) ) ) - or - exists(SummarizedCallable c, ParameterPosition pos, ParamNode p | - n = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and - p.isParameterOf(c, pos) and - result = getNodeType(p) - ) } /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ @@ -601,10 +640,7 @@ module Private { predicate summaryPostUpdateNode(Node post, Node pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(c, pos) - or - pre = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and - post = summaryNode(c, TSummaryNodeClearsContentState(pos, true)) + pre.(ParamNode).isParameterOf(inject(c), pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -627,9 +663,7 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) | - c.clearsContent(ppos, _) - or + exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -658,9 +692,10 @@ module Private { preservesValue = false and not summary(c, inputContents, outputContents, true) ) or - exists(SummarizedCallable c, ParameterPosition pos | - pred.(ParamNode).isParameterOf(c, pos) and - succ = summaryNode(c, TSummaryNodeClearsContentState(pos, _)) and + exists(SummarizedCallable c, SummaryComponentStack s | + pred = summaryNodeInputState(c, s.tail()) and + succ = summaryNodeInputState(c, s) and + s.head() = [SummaryComponent::withContent(_), SummaryComponent::withoutContent(_)] and preservesValue = true ) } @@ -669,9 +704,9 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, Content c, Node succ) { + predicate summaryReadStep(Node pred, ContentSet c, Node succ) { exists(SummarizedCallable sc, SummaryComponentStack s | - pred = summaryNodeInputState(sc, s.drop(1)) and + pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and SummaryComponent::content(c) = s.head() ) @@ -681,14 +716,26 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, Content c, Node succ) { + predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and - succ = summaryNodeOutputState(sc, s.drop(1)) and + succ = summaryNodeOutputState(sc, s.tail()) and SummaryComponent::content(c) = s.head() ) } + /** + * Holds if there is a jump step from `pred` to `succ`, which is synthesized + * from a flow summary. + */ + predicate summaryJumpStep(Node pred, Node succ) { + exists(SummaryComponentStack s | + s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and + pred = summaryNodeOutputState(_, s) and + succ = summaryNodeInputState(_, s) + ) + } + /** * Holds if values stored inside content `c` are cleared at `n`. `n` is a * synthesized summary node, so in order for values to be cleared at calls @@ -708,10 +755,23 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, Content c) { - exists(SummarizedCallable sc, ParameterPosition pos | - n = summaryNode(sc, TSummaryNodeClearsContentState(pos, true)) and - sc.clearsContent(pos, c) + predicate summaryClearsContent(Node n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = summaryNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withoutContent(c) + ) + } + + /** + * Holds if the value that is being tracked is expected to be stored inside + * content `c` at `n`. + */ + predicate summaryExpectsContent(Node n, ContentSet c) { + exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | + n = summaryNode(sc, state) and + state.isInputState(sc, stack) and + stack.head() = SummaryComponent::withContent(c) ) } @@ -719,55 +779,96 @@ module Private { private predicate viableParam( DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p ) { - p.isParameterOf(sc, ppos) and - sc = viableCallable(call) - } - - /** - * Holds if values stored inside content `c` are cleared inside a - * callable to which `arg` is an argument. - * - * In such cases, it is important to prevent use-use flow out of - * `arg` (see comment for `summaryClearsContent`). - */ - predicate summaryClearsContentArg(ArgNode arg, Content c) { - exists(DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos | - argumentPositionMatch(call, arg, ppos) and - viableParam(call, sc, ppos, _) and - sc.clearsContent(ppos, c) + exists(DataFlowCallable c | + c = inject(sc) and + p.isParameterOf(c, ppos) and + c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg) { - exists(ParameterPosition ppos, SummarizedCallable sc | + private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) ) } - pragma[nomagic] - private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) { - exists(DataFlowCall call | - result = summaryArgParam0(call, arg) and - out = rk.getAnOutNode(call) + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExpects` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + viableParam(_, _, _, p) and + n = p and + clearsOrExpects = false + or + exists(Node mid, boolean clearsOrExpectsMid | + paramReachesLocal(p, mid, clearsOrExpectsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExpects = true + else clearsOrExpects = clearsOrExpectsMid ) } /** - * Holds if `arg` flows to `out` using a simple flow summary, that is, a flow - * summary without reads and stores. + * Holds if use-use flow starting from `arg` should be prohibited. + * + * This is the case when `arg` is the argument of a call that targets a + * flow summary where the corresponding parameter either clears contents + * or expects contents. + */ + pragma[nomagic] + predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and + p = summaryArgParam0(_, arg, sc) and + p.isParameterOf(_, pragma[only_bind_into](ppos)) and + isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) + ) + } + + bindingset[ret] + private ParamNode summaryArgParam( + ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + ) { + exists(DataFlowCall call, ReturnKindExt rk | + result = summaryArgParam0(call, arg, sc) and + ret.getKind() = pragma[only_bind_into](rk) and + out = pragma[only_bind_into](rk).getAnOutNode(call) + ) + } + + /** + * Holds if `arg` flows to `out` using a simple value-preserving flow + * summary, that is, a flow summary without reads and stores. * * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summaryThroughStep(ArgNode arg, Node out, boolean preservesValue) { - exists(ReturnKindExt rk, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, rk, out), ret, preservesValue) and - ret.getKind() = rk + predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { + exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and + ret.getKind() = pragma[only_bind_into](rk) and + out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } + /** + * Holds if `arg` flows to `out` using a simple flow summary involving taint + * step, that is, a flow summary without reads and stores. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { + exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + } + /** * Holds if there is a read(+taint) of `c` from `arg` to `out` using a * flow summary. @@ -775,11 +876,10 @@ module Private { * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summaryGetterStep(ArgNode arg, Content c, Node out) { - exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, rk, out), c, mid) and - summaryLocalStep(mid, ret, _) and - ret.getKind() = rk + predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(Node mid, ReturnNodeExt ret | + summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + summaryLocalStep(mid, ret, _) ) } @@ -790,44 +890,53 @@ module Private { * NOTE: This step should not be used in global data-flow/taint-tracking, but may * be useful to include in the exposed local data-flow/taint-tracking relations. */ - predicate summarySetterStep(ArgNode arg, Content c, Node out) { - exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, rk, out), mid, _) and - summaryStoreStep(mid, c, ret) and - ret.getKind() = rk + predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { + exists(Node mid, ReturnNodeExt ret | + summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + summaryStoreStep(mid, c, ret) ) } } /** - * Provides a means of translating externally (e.g., CSV) defined flow + * Provides a means of translating externally (e.g., MaD) defined flow * summaries into a `SummarizedCallable`s. */ module External { /** Holds if `spec` is a relevant external specification. */ private predicate relevantSpec(string spec) { - summaryElement(_, spec, _, _) or - summaryElement(_, _, spec, _) or - sourceElement(_, spec, _) or - sinkElement(_, spec, _) + summaryElement(_, spec, _, _, _) or + summaryElement(_, _, spec, _, _) or + sourceElement(_, spec, _, _) or + sinkElement(_, spec, _, _) } private class AccessPathRange extends AccessPath::Range { AccessPathRange() { relevantSpec(this) } } - /** Holds if specification component `c` parses as parameter `n`. */ + /** Holds if specification component `token` parses as parameter `pos`. */ predicate parseParam(AccessPathToken token, ArgumentPosition pos) { token.getName() = "Parameter" and pos = parseParamBody(token.getAnArgument()) } - /** Holds if specification component `c` parses as argument `n`. */ + /** Holds if specification component `token` parses as argument `pos`. */ predicate parseArg(AccessPathToken token, ParameterPosition pos) { token.getName() = "Argument" and pos = parseArgBody(token.getAnArgument()) } + /** Holds if specification component `token` parses as synthetic global `sg`. */ + predicate parseSynthGlobal(AccessPathToken token, string sg) { + token.getName() = "SyntheticGlobal" and + sg = token.getAnArgument() + } + + private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal { + SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) } + } + private SummaryComponent interpretComponent(AccessPathToken token) { exists(ParameterPosition pos | parseArg(token, pos) and result = SummaryComponent::argument(pos) @@ -839,6 +948,10 @@ module Private { or token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind()) or + exists(string sg | + parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg) + ) + or result = interpretComponentSpecific(token) } @@ -875,13 +988,26 @@ module Private { } private class SummarizedCallableExternal extends SummarizedCallable { - SummarizedCallableExternal() { summaryElement(this, _, _, _) } + SummarizedCallableExternal() { summaryElement(this, _, _, _, _) } + + private predicate relevantSummaryElementGenerated( + AccessPath inSpec, AccessPath outSpec, string kind + ) { + summaryElement(this, inSpec, outSpec, kind, true) and + not summaryElement(this, _, _, _, false) + } + + private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) { + summaryElement(this, inSpec, outSpec, kind, false) + or + this.relevantSummaryElementGenerated(inSpec, outSpec, kind) + } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(AccessPath inSpec, AccessPath outSpec, string kind | - summaryElement(this, inSpec, outSpec, kind) and + this.relevantSummaryElement(inSpec, outSpec, kind) and interpretSpec(inSpec, input) and interpretSpec(outSpec, output) | @@ -890,6 +1016,12 @@ module Private { kind = "taint" and preservesValue = false ) } + + override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) } + + override predicate hasProvenance(boolean generated) { + summaryElement(this, _, _, _, generated) + } } /** Holds if component `c` of specification `spec` cannot be parsed. */ @@ -910,7 +1042,7 @@ module Private { private predicate sourceElementRef(InterpretNode ref, AccessPath output, string kind) { exists(SourceOrSinkElement e | - sourceElement(e, output, kind) and + sourceElement(e, output, kind, _) and if outputNeedsReference(output.getToken(0)) then e = ref.getCallTarget() else e = ref.asElement() @@ -919,7 +1051,7 @@ module Private { private predicate sinkElementRef(InterpretNode ref, AccessPath input, string kind) { exists(SourceOrSinkElement e | - sinkElement(e, input, kind) and + sinkElement(e, input, kind, _) and if inputNeedsReference(input.getToken(0)) then e = ref.getCallTarget() else e = ref.asElement() @@ -1000,7 +1132,7 @@ module Private { } /** - * Holds if `node` is specified as a source with the given kind in a CSV flow + * Holds if `node` is specified as a source with the given kind in a MaD flow * model. */ predicate isSourceNode(InterpretNode node, string kind) { @@ -1011,7 +1143,7 @@ module Private { } /** - * Holds if `node` is specified as a sink with the given kind in a CSV flow + * Holds if `node` is specified as a sink with the given kind in a MaD flow * model. */ predicate isSinkNode(InterpretNode node, string kind) { @@ -1024,8 +1156,8 @@ module Private { /** Provides a query predicate for outputting a set of relevant flow summaries. */ module TestOutput { - /** A flow summary to include in the `summary/3` query predicate. */ - abstract class RelevantSummarizedCallable extends SummarizedCallable { + /** A flow summary to include in the `summary/1` query predicate. */ + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { /** Gets the string representation of this callable used by `summary/1`. */ abstract string getCallableCsv(); @@ -1033,8 +1165,18 @@ module Private { predicate relevantSummary( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - this.propagatesFlow(input, output, preservesValue) + super.propagatesFlow(input, output, preservesValue) } + + string toString() { result = super.toString() } + } + + /** A model to include in the `neutral/1` query predicate. */ + abstract class RelevantNeutralCallable instanceof NeutralCallable { + /** Gets the string representation of this callable used by `neutral/1`. */ + abstract string getCallableCsv(); + + string toString() { result = super.toString() } } /** Render the kind in the format used in flow summaries. */ @@ -1044,9 +1186,17 @@ module Private { preservesValue = false and result = "taint" } + private string renderProvenance(SummarizedCallable c) { + if c.isAutoGenerated() then result = "generated" else result = "manual" + } + + private string renderProvenanceNeutral(NeutralCallable c) { + if c.isAutoGenerated() then result = "generated" else result = "manual" + } + /** * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. - * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind", + * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance", * ext is hardcoded to empty. */ query predicate summary(string csv) { @@ -1056,8 +1206,23 @@ module Private { | c.relevantSummary(input, output, preservesValue) and csv = - c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" + - getComponentStackCsv(output) + ";" + renderKind(preservesValue) + c.getCallableCsv() // Callable information + + getComponentStackCsv(input) + ";" // input + + getComponentStackCsv(output) + ";" // output + + renderKind(preservesValue) + ";" // kind + + renderProvenance(c) // provenance + ) + } + + /** + * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes. + * The syntax is: "namespace;type;name;signature;provenance"", + */ + query predicate neutral(string csv) { + exists(RelevantNeutralCallable c | + csv = + c.getCallableCsv() // Callable information + + renderProvenanceNeutral(c) // provenance ) } } @@ -1071,19 +1236,21 @@ module Private { */ module RenderSummarizedCallable { /** A summarized callable to include in the graph. */ - abstract class RelevantSummarizedCallable extends SummarizedCallable { } + abstract class RelevantSummarizedCallable instanceof SummarizedCallable { + string toString() { result = super.toString() } + } private newtype TNodeOrCall = MkNode(Node n) { exists(RelevantSummarizedCallable c | n = summaryNode(c, _) or - n.(ParamNode).isParameterOf(c, _) + n.(ParamNode).isParameterOf(inject(c), _) ) } or MkCall(DataFlowCall call) { call = summaryDataFlowCall(_) and - call.getEnclosingCallable() instanceof RelevantSummarizedCallable + call.getEnclosingCallable() = inject(any(RelevantSummarizedCallable c)) } private class NodeOrCall extends TNodeOrCall { @@ -1123,7 +1290,7 @@ module Private { if preservesValue = true then value = "value" else value = "taint" ) or - exists(Content c | + exists(ContentSet c | Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and value = "read (" + c + ")" or @@ -1133,6 +1300,10 @@ module Private { Private::Steps::summaryClearsContent(a.asNode(), c) and b = a and value = "clear (" + c + ")" + or + Private::Steps::summaryExpectsContent(a.asNode(), c) and + b = a and + value = "expect (" + c + ")" ) or summaryPostUpdateNode(b.asNode(), a.asNode()) and diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 4d8e19461df..fd82938968a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -3,6 +3,7 @@ */ private import go +private import DataFlowDispatch private import DataFlowPrivate private import DataFlowUtil private import FlowSummaryImpl::Private @@ -14,39 +15,12 @@ private module FlowSummaries { private import semmle.go.dataflow.FlowSummary as F } -/** Holds if `i` is a valid parameter position. */ -predicate parameterPosition(int i) { - i = [-1 .. any(DataFlowCallable c).getType().getNumParameter()] -} +class SummarizedCallableBase = Callable; + +DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c } /** Gets the parameter position of the instance parameter. */ -int instanceParameterPosition() { result = -1 } - -/** A parameter position represented by an integer. */ -class ParameterPosition extends int { - ParameterPosition() { parameterPosition(this) } -} - -/** An argument position represented by an integer. */ -class ArgumentPosition extends int { - ArgumentPosition() { parameterPosition(this) } -} - -/** Holds if arguments at position `apos` match parameters at position `ppos`. */ -pragma[inline] -predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } - -/** - * Holds if `arg` is an argument of `call` with an argument position that matches - * parameter position `ppos`. - */ -pragma[noinline] -predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) { - exists(ArgumentPosition apos | - arg.argumentOf(call, apos) and - parameterMatch(ppos, apos) - ) -} +ArgumentPosition instanceParameterPosition() { result = -1 } /** Gets the textual representation of a parameter position in the format used for flow summaries. */ string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() } @@ -66,35 +40,47 @@ DataFlowCall summaryDataFlowCall(Node receiver) { DataFlowType getContentType(Content c) { result = c.getType() } /** Gets the return type of kind `rk` for callable `c`. */ -DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { - result = c.getType().getResultType(rk.getIndex()) -} +DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } /** * Gets the type of the `i`th parameter in a synthesized call that targets a * callback of type `t`. */ -DataFlowType getCallbackParameterType(DataFlowType t, int i) { none() } +bindingset[t, pos] +DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) { any() } /** * Gets the return type of kind `rk` in a synthesized call that targets a * callback of type `t`. */ -DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() } +DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { any() } + +/** Gets the type of synthetic global `sg`. */ +DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any() } /** * Holds if an external flow summary exists for `c` with input specification - * `input`, output specification `output`, and kind `kind`. + * `input`, output specification `output`, kind `kind`, and a flag `generated` + * stating whether the summary is autogenerated. */ -predicate summaryElement(DataFlowCallable c, string input, string output, string kind) { +predicate summaryElement( + SummarizedCallableBase c, string input, string output, string kind, boolean generated +) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and + summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and c.asFunction() = interpretElement(namespace, type, subtypes, name, signature, ext).asEntity() ) } +/** + * Holds if a neutral model exists for `c`, which means that there is no + * flow through `c`. The flag `generated` states whether the model is autogenerated. + * Note. Neutral models have not been implemented for Go. + */ +predicate neutralElement(SummarizedCallable c, boolean generated) { none() } + /** Gets the summary component for specification component `c`, if any. */ bindingset[c] SummaryComponent interpretComponentSpecific(string c) { @@ -166,26 +152,28 @@ class SourceOrSinkElement extends TSourceOrSinkElement { /** * Holds if an external source specification exists for `e` with output specification - * `output` and kind `kind`. + * `output`, kind `kind`, and a flag `generated` stating whether the source specification is + * autogenerated. */ -predicate sourceElement(SourceOrSinkElement e, string output, string kind) { +predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and + sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and e = interpretElement(namespace, type, subtypes, name, signature, ext) ) } /** * Holds if an external sink specification exists for `e` with input specification - * `input` and kind `kind`. + * `input`, kind `kind` and a flag `generated` stating whether the sink specification is + * autogenerated. */ -predicate sinkElement(SourceOrSinkElement e, string input, string kind) { +predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and + sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and e = interpretElement(namespace, type, subtypes, name, signature, ext) ) } @@ -271,7 +259,10 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { ) } -/** Holds if specification component `c` parses as return value `n`. */ +/** + * Holds if specification component `c` parses as return value `n` or a range + * containing `n`. + */ predicate parseReturn(AccessPathToken c, int n) { ( c = "ReturnValue" and n = 0 @@ -292,8 +283,10 @@ private int parseConstantOrRange(string arg) { ) } +/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */ bindingset[arg] ArgumentPosition parseParamBody(string arg) { result = parseConstantOrRange(arg) } +/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */ bindingset[arg] ParameterPosition parseArgBody(string arg) { result = parseConstantOrRange(arg) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 2a93253c480..77dadd8e3a8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -9,12 +9,14 @@ private import FlowSummaryImpl as FlowSummaryImpl * Holds if taint can flow from `src` to `sink` in zero or more * local (intra-procedural) steps. */ +pragma[inline] predicate localTaint(DataFlow::Node src, DataFlow::Node sink) { localTaintStep*(src, sink) } /** * Holds if taint can flow from `src` to `sink` in zero or more * local (intra-procedural) steps. */ +pragma[inline] predicate localExprTaint(Expr src, Expr sink) { localTaint(DataFlow::exprNode(src), DataFlow::exprNode(sink)) } @@ -27,7 +29,7 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { localAdditionalTaintStep(src, sink) or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::Steps::summaryThroughStep(src, sink, false) + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _) } private Type getElementType(Type containerType) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 4e613ba727e..bf937b6de31 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -61,15 +61,32 @@ abstract class Configuration extends DataFlow::Configuration { * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); + override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink) { none() } + + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -101,8 +128,23 @@ abstract class Configuration extends DataFlow::Configuration { } /** - * Holds if the additional taint propagation step from `node1` to `node2` - * must be taken into account in the analysis. + * DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. + * + * Holds if taint propagation through nodes guarded by `guard` is prohibited + * when the flow state is `state`. + */ + deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { + none() + } + + deprecated final override predicate isBarrierGuard( + DataFlow::BarrierGuard guard, DataFlow::FlowState state + ) { + this.isSanitizerGuard(guard, state) + } + + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } @@ -111,8 +153,31 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { - (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { + ( + this.isSink(node) or + this.isSink(node, _) or + this.isAdditionalTaintStep(node, _) or + this.isAdditionalTaintStep(node, _, _, _) + ) and defaultImplicitTaintRead(node, c) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 4e613ba727e..bf937b6de31 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -61,15 +61,32 @@ abstract class Configuration extends DataFlow::Configuration { * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); + override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink) { none() } + + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -101,8 +128,23 @@ abstract class Configuration extends DataFlow::Configuration { } /** - * Holds if the additional taint propagation step from `node1` to `node2` - * must be taken into account in the analysis. + * DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. + * + * Holds if taint propagation through nodes guarded by `guard` is prohibited + * when the flow state is `state`. + */ + deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { + none() + } + + deprecated final override predicate isBarrierGuard( + DataFlow::BarrierGuard guard, DataFlow::FlowState state + ) { + this.isSanitizerGuard(guard, state) + } + + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } @@ -111,8 +153,31 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { - (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. + * This step is only applicable in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { + ( + this.isSink(node) or + this.isSink(node, _) or + this.isAdditionalTaintStep(node, _) or + this.isAdditionalTaintStep(node, _, _, _) + ) and defaultImplicitTaintRead(node, c) } diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index 322d17a420a..b8b85d634c8 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -103,6 +103,14 @@ module SQL { /** A string that might identify package `go-pg/pg/orm` or a specific version of it. */ private string gopgorm() { result = package("github.com/go-pg/pg", "orm") } + /** A string that might identify package `github.com/rqlite/gorqlite` or `github.com/raindog308/gorqlite` or a specific version of it. */ + private string gorqlite() { + result = package(["github.com/rqlite/gorqlite", "github.com/raindog308/gorqlite"], "") + } + + /** A string that might identify package `github.com/gogf/gf/database/gdb` or a specific version of it. */ + private string gogf() { result = package("github.com/gogf/gf", "database/gdb") } + /** * A string argument to an API of `go-pg/pg` that is directly interpreted as SQL without * taking syntactic structure into account. @@ -152,6 +160,65 @@ module SQL { } } + /** + * A string argument to an API of `github.com/rqlite/gorqlite`, or a specific version of it, that is directly interpreted as SQL without + * taking syntactic structure into account. + */ + private class GorqliteQueryString extends Range { + GorqliteQueryString() { + // func (conn *Connection) Query(sqlStatements []string) (results []QueryResult, err error) + // func (conn *Connection) QueryOne(sqlStatement string) (qr QueryResult, err error) + // func (conn *Connection) Queue(sqlStatements []string) (seq int64, err error) + // func (conn *Connection) QueueOne(sqlStatement string) (seq int64, err error) + // func (conn *Connection) Write(sqlStatements []string) (results []WriteResult, err error) + // func (conn *Connection) WriteOne(sqlStatement string) (wr WriteResult, err error) + exists(Method m, string name | m.hasQualifiedName(gorqlite(), "Connection", name) | + name = ["Query", "QueryOne", "Queue", "QueueOne", "Write", "WriteOne"] and + this = m.getACall().getArgument(0) + ) + } + } + + /** + * A string argument to an API of `github.com/gogf/gf/database/gdb`, or a specific version of it, that is directly interpreted as SQL without + * taking syntactic structure into account. + */ + private class GogfQueryString extends Range { + GogfQueryString() { + exists(Method m, string name | m.implements(gogf(), ["DB", "Core", "TX"], name) | + // func (c *Core) Exec(sql string, args ...interface{}) (result sql.Result, err error) + // func (c *Core) GetAll(sql string, args ...interface{}) (Result, error) + // func (c *Core) GetArray(sql string, args ...interface{}) ([]Value, error) + // func (c *Core) GetCount(sql string, args ...interface{}) (int, error) + // func (c *Core) GetOne(sql string, args ...interface{}) (Record, error) + // func (c *Core) GetValue(sql string, args ...interface{}) (Value, error) + // func (c *Core) Prepare(sql string, execOnMaster ...bool) (*Stmt, error) + // func (c *Core) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) + // func (c *Core) Raw(rawSql string, args ...interface{}) *Model + name = + [ + "Query", "Exec", "Prepare", "GetAll", "GetOne", "GetValue", "GetArray", "GetCount", + "Raw" + ] and + this = m.getACall().getArgument(0) + or + // func (c *Core) GetScan(pointer interface{}, sql string, args ...interface{}) error + // func (c *Core) GetStruct(pointer interface{}, sql string, args ...interface{}) error + // func (c *Core) GetStructs(pointer interface{}, sql string, args ...interface{}) error + name = ["GetScan", "GetStruct", "GetStructs"] and + this = m.getACall().getArgument(1) + or + // func (c *Core) DoCommit(ctx context.Context, link Link, sql string, args []interface{}) (newSql string, newArgs []interface{}, err error) + // func (c *Core) DoExec(ctx context.Context, link Link, sql string, args ...interface{}) (result sql.Result, err error) + // func (c *Core) DoGetAll(ctx context.Context, link Link, sql string, args ...interface{}) (result Result, err error) + // func (c *Core) DoPrepare(ctx context.Context, link Link, sql string) (*Stmt, error) + // func (c *Core) DoQuery(ctx context.Context, link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) + name = ["DoGetAll", "DoQuery", "DoExec", "DoCommit", "DoPrepare"] and + this = m.getACall().getArgument(2) + ) + } + } + /** A taint model for various methods on the struct `Formatter` of `go-pg/pg/orm`. */ private class PgOrmFormatterFunction extends TaintTracking::FunctionModel, Method { FunctionInput i; diff --git a/go/ql/lib/semmle/go/frameworks/SystemCommandExecutors.qll b/go/ql/lib/semmle/go/frameworks/SystemCommandExecutors.qll index c2d9929fa54..1e4b7637581 100644 --- a/go/ql/lib/semmle/go/frameworks/SystemCommandExecutors.qll +++ b/go/ql/lib/semmle/go/frameworks/SystemCommandExecutors.qll @@ -20,7 +20,9 @@ private class ShellOrSudoExecution extends SystemCommandExecution::Range, DataFl override DataFlow::Node getCommandName() { result = this.getAnArgument() } - override predicate doubleDashIsSanitizing() { shellCommand.getStringValue().matches("%git") } + override predicate doubleDashIsSanitizing() { + shellCommand.getStringValue().matches("%" + ["git", "rsync"]) + } } private class SystemCommandExecutors extends SystemCommandExecution::Range, DataFlow::CallNode { @@ -126,7 +128,7 @@ private string getASudoCommand() { "fakeroot", "fakeroot-sysv", "su", "fakeroot-tcp", "fstab-decode", "jrunscript", "nohup", "parallel", "find", "pkexec", "sg", "sem", "runcon", "sudoedit", "runuser", "stdbuf", "system", "timeout", "xargs", "time", "awk", "gawk", "mawk", "nawk", "doas", "git", "access", - "vsys", "userv", "sus", "super" + "vsys", "userv", "sus", "super", "rsync" ] } diff --git a/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll b/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll index 0cd2ff2bc79..294e1048b29 100644 --- a/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll +++ b/go/ql/lib/semmle/go/security/AllocationSizeOverflow.qll @@ -48,11 +48,11 @@ module AllocationSizeOverflow { * Holds if `nd` is at a position where overflow might occur, and its result is used to compute * allocation size `allocsz`. */ - predicate isSink(DataFlow::Node nd, DataFlow::Node allocsz) { + predicate isSinkWithAllocationSize(DataFlow::Node nd, DataFlow::Node allocsz) { nd.(Sink).getAllocationSize() = allocsz } - override predicate isSink(DataFlow::Node nd) { isSink(nd, _) } + override predicate isSink(DataFlow::Node nd) { isSinkWithAllocationSize(nd, _) } override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { additionalStep(pred, succ) diff --git a/go/ql/lib/semmle/go/security/CommandInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/CommandInjectionCustomizations.qll index 1550d68dc03..a8f8269a968 100644 --- a/go/ql/lib/semmle/go/security/CommandInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/CommandInjectionCustomizations.qll @@ -37,9 +37,7 @@ module CommandInjection { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A source of untrusted data, considered as a taint source for command injection. */ - class UntrustedFlowAsSource extends Source { - UntrustedFlowAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { } /** A command name, considered as a taint sink for command injection. */ class CommandNameAsSink extends Sink { diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index fbe73ae1128..060832cfffc 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -109,7 +109,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { * not also in a right-shift expression. We allow this case because it is * a common pattern to serialise `byte(v)`, `byte(v >> 8)`, and so on. */ - predicate isSink(DataFlow::TypeCastNode sink, int bitSize) { + predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) { sink.asExpr() instanceof ConversionExpr and exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType | bitSize = integerType.getSize() @@ -125,7 +125,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, sinkBitSize) } + override predicate isSink(DataFlow::Node sink) { this.isSinkWithBitSize(sink, sinkBitSize) } override predicate isSanitizer(DataFlow::Node node) { // To catch flows that only happen on 32-bit architectures we @@ -140,7 +140,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { override predicate isSanitizerOut(DataFlow::Node node) { exists(int bitSize | isIncorrectIntegerConversion(sourceBitSize, bitSize) | - this.isSink(node, bitSize) + this.isSinkWithBitSize(node, bitSize) ) } } diff --git a/go/ql/lib/semmle/go/security/InsecureRandomness.qll b/go/ql/lib/semmle/go/security/InsecureRandomness.qll index 6de3071b598..38916389c9b 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomness.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomness.qll @@ -25,10 +25,10 @@ module InsecureRandomness { override predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkWithKind(sink, _) } /** Holds if `sink` is a sink for this configuration with kind `kind`. */ - predicate isSink(Sink sink, string kind) { kind = sink.getKind() } + predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } diff --git a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll index 35b4625fe18..73d5f4f9a82 100644 --- a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll @@ -33,9 +33,7 @@ module LogInjection { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A source of untrusted data, considered as a taint source for log injection. */ - class UntrustedFlowAsSource extends Source { - UntrustedFlowAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { } /** An argument to a logging mechanism. */ class LoggerSink extends Sink { diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 80b9bb4a126..c6fdefd4a2b 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -117,9 +117,7 @@ module OpenUrlRedirect { } /** A sink for an open redirect, considered as a sink for safe URL flow. */ -private class SafeUrlSink extends SafeUrlFlow::Sink { - SafeUrlSink() { this instanceof OpenUrlRedirect::Sink } -} +private class SafeUrlSink extends SafeUrlFlow::Sink instanceof OpenUrlRedirect::Sink { } /** * A read of a field considered unsafe to redirect to, considered as a sanitizer for a safe @@ -128,7 +126,7 @@ private class SafeUrlSink extends SafeUrlFlow::Sink { private class UnsafeFieldReadSanitizer extends SafeUrlFlow::SanitizerEdge { UnsafeFieldReadSanitizer() { exists(DataFlow::FieldReadNode frn, string name | - name = ["User", "RawQuery", "Fragment", "User"] and + name = ["User", "RawQuery", "Fragment"] and frn.getField().hasQualifiedName("net/url", "URL") | this = frn.getBase() diff --git a/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll b/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll index 82233a1e79b..bdc2bd0cf1b 100644 --- a/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll +++ b/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll @@ -27,9 +27,7 @@ module ReflectedXss { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A shared XSS sanitizer as a sanitizer for reflected XSS. */ - private class SharedXssSanitizer extends Sanitizer { - SharedXssSanitizer() { this instanceof SharedXss::Sanitizer } - } + private class SharedXssSanitizer extends Sanitizer instanceof SharedXss::Sanitizer { } /** A shared XSS sanitizer guard as a sanitizer guard for reflected XSS. */ deprecated private class SharedXssSanitizerGuard extends SanitizerGuard { @@ -46,7 +44,5 @@ module ReflectedXss { class UntrustedFlowAsSource extends Source, UntrustedFlowSource { } /** An arbitrary XSS sink, considered as a flow sink for stored XSS. */ - private class AnySink extends Sink { - AnySink() { this instanceof SharedXss::Sink } - } + private class AnySink extends Sink instanceof SharedXss::Sink { } } diff --git a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll index b11157daa06..26aff199a5c 100644 --- a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll +++ b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll @@ -102,9 +102,7 @@ module RequestForgery { } /** A sink for request forgery, considered as a sink for safe URL flow. */ -private class SafeUrlSink extends SafeUrlFlow::Sink { - SafeUrlSink() { this instanceof RequestForgery::Sink } -} +private class SafeUrlSink extends SafeUrlFlow::Sink instanceof RequestForgery::Sink { } /** * A read of a field considered unsafe for request forgery, considered as a sanitizer for a safe diff --git a/go/ql/lib/semmle/go/security/SqlInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/SqlInjectionCustomizations.qll index 11e794a9f1e..9687eea91a9 100644 --- a/go/ql/lib/semmle/go/security/SqlInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/SqlInjectionCustomizations.qll @@ -33,17 +33,11 @@ module SqlInjection { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A source of untrusted data, considered as a taint source for SQL injection. */ - class UntrustedFlowAsSource extends Source { - UntrustedFlowAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { } /** An SQL string, considered as a taint sink for SQL injection. */ - class SqlQueryAsSink extends Sink { - SqlQueryAsSink() { this instanceof SQL::QueryString } - } + class SqlQueryAsSink extends Sink instanceof SQL::QueryString { } /** A NoSql query, considered as a taint sink for SQL injection. */ - class NoSqlQueryAsSink extends Sink { - NoSqlQueryAsSink() { this instanceof NoSql::Query } - } + class NoSqlQueryAsSink extends Sink instanceof NoSql::Query { } } diff --git a/go/ql/lib/semmle/go/security/StoredXssCustomizations.qll b/go/ql/lib/semmle/go/security/StoredXssCustomizations.qll index e48f17181ca..7d468df2607 100644 --- a/go/ql/lib/semmle/go/security/StoredXssCustomizations.qll +++ b/go/ql/lib/semmle/go/security/StoredXssCustomizations.qll @@ -24,9 +24,7 @@ module StoredXss { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A shared XSS sanitizer as a sanitizer for stored XSS. */ - private class SharedXssSanitizer extends Sanitizer { - SharedXssSanitizer() { this instanceof SharedXss::Sanitizer } - } + private class SharedXssSanitizer extends Sanitizer instanceof SharedXss::Sanitizer { } /** A shared XSS sanitizer guard as a sanitizer guard for stored XSS. */ deprecated private class SharedXssSanitizerGuard extends SanitizerGuard { @@ -59,7 +57,5 @@ module StoredXss { } /** An arbitrary XSS sink, considered as a flow sink for stored XSS. */ - private class AnySink extends Sink { - AnySink() { this instanceof SharedXss::Sink } - } + private class AnySink extends Sink instanceof SharedXss::Sink { } } diff --git a/go/ql/lib/semmle/go/security/TaintedPathCustomizations.qll b/go/ql/lib/semmle/go/security/TaintedPathCustomizations.qll index 61499340de3..0b4c41276d7 100644 --- a/go/ql/lib/semmle/go/security/TaintedPathCustomizations.qll +++ b/go/ql/lib/semmle/go/security/TaintedPathCustomizations.qll @@ -61,9 +61,7 @@ module TaintedPath { } /** A source of untrusted data, considered as a taint source for path traversal. */ - class UntrustedFlowAsSource extends Source { - UntrustedFlowAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { } /** A path expression, considered as a taint sink for path traversal. */ class PathAsSink extends Sink { diff --git a/go/ql/lib/semmle/go/security/XPathInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/XPathInjectionCustomizations.qll index d16c6cc1312..3e9484506e0 100644 --- a/go/ql/lib/semmle/go/security/XPathInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/XPathInjectionCustomizations.qll @@ -32,12 +32,8 @@ module XPathInjection { abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** A source of untrusted data, used in an XPath expression. */ - class UntrustedFlowAsSource extends Source { - UntrustedFlowAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { } /** An XPath expression string, considered as a taint sink for XPath injection. */ - class XPathExpressionStringAsSink extends Sink { - XPathExpressionStringAsSink() { this instanceof XPath::XPathExpressionString } - } + class XPathExpressionStringAsSink extends Sink instanceof XPath::XPathExpressionString { } } diff --git a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll index da2c25aae28..4bc407f871d 100644 --- a/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll +++ b/go/ql/lib/semmle/go/security/ZipSlipCustomizations.qll @@ -73,9 +73,8 @@ module ZipSlip { } /** A path-traversal sink, considered as a taint sink for zip slip. */ - class TaintedPathSinkAsSink extends Sink { + class TaintedPathSinkAsSink extends Sink instanceof TaintedPath::Sink { TaintedPathSinkAsSink() { - this instanceof TaintedPath::Sink and // Exclude `os.Symlink`, which is treated specifically in query `go/unsafe-unzip-symlink`. not exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("os", "Symlink") | this = c.getAnArgument() @@ -84,9 +83,7 @@ module ZipSlip { } /** A path-traversal sanitizer, considered as a sanitizer for zip slip. */ - class TaintedPathSanitizerAsSanitizer extends Sanitizer { - TaintedPathSanitizerAsSanitizer() { this instanceof TaintedPath::Sanitizer } - } + class TaintedPathSanitizerAsSanitizer extends Sanitizer instanceof TaintedPath::Sanitizer { } pragma[noinline] private predicate taintedPathGuardChecks( diff --git a/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/exprs.ql b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/exprs.ql new file mode 100644 index 00000000000..6d0065def6e --- /dev/null +++ b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/exprs.ql @@ -0,0 +1,28 @@ +class Expr_ extends @expr { + string toString() { result = "Expr" } +} + +class ExprParent_ extends @exprparent { + string toString() { result = "ExprParent" } +} + +/** + * The last index, 55 (errorexpr), has been deleted. Index 0 (badexpr) should + * be used instead. + */ +bindingset[old_index] +int new_index(int old_index) { + if old_index = 55 + then result = 0 // badexpr + else result = old_index +} + +// The schema for exprs is: +// +// exprs(unique int id: @expr, +// int kind: int ref, +// int parent: @exprparent ref, +// int idx: int ref); +from Expr_ expr, int new_kind, ExprParent_ parent, int idx, int old_kind +where exprs(expr, old_kind, parent, idx) and new_kind = new_index(old_kind) +select expr, new_kind, parent, idx diff --git a/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/go.dbscheme b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/go.dbscheme new file mode 100644 index 00000000000..a58b81b1b4c --- /dev/null +++ b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/go.dbscheme @@ -0,0 +1,546 @@ +/** Auto-generated dbscheme; do not edit. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @namedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int named: @namedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @namedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @namedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/old.dbscheme b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/old.dbscheme new file mode 100644 index 00000000000..90fa7836e0a --- /dev/null +++ b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/old.dbscheme @@ -0,0 +1,547 @@ +/** Auto-generated dbscheme; do not edit. */ + + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +compilations(unique int id: @compilation, string cwd: string ref); + +#keyset[id, num] +compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref); + +#keyset[id, num, kind] +compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref); + +diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref); + +compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref); + +#keyset[id, num] +compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref); + +diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref, + string full_error_message: string ref, int location: @location ref); + +locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref, + int endLine: int ref, int endColumn: int ref); + +numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref); + +files(unique int id: @file, string name: string ref); + +folders(unique int id: @folder, string name: string ref); + +containerparent(int parent: @container ref, unique int child: @container ref); + +has_location(unique int locatable: @locatable ref, int location: @location ref); + +#keyset[parent, idx] +comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref); + +comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref); + +doc_comments(unique int node: @documentable ref, int comment: @comment_group ref); + +#keyset[parent, idx] +exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref); + +literals(unique int expr: @expr ref, string value: string ref, string raw: string ref); + +constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref); + +fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref); + +typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref); + +#keyset[parent, idx] +stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref); + +#keyset[parent, idx] +decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref); + +#keyset[parent, idx] +specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref); + +scopes(unique int id: @scope, int kind: int ref); + +scopenesting(unique int inner: @scope ref, int outer: @scope ref); + +scopenodes(unique int node: @scopenode ref, int scope: @localscope ref); + +objects(unique int id: @object, int kind: int ref, string name: string ref); + +objectscopes(unique int object: @object ref, int scope: @scope ref); + +objecttypes(unique int object: @object ref, int tp: @type ref); + +methodreceivers(unique int method: @object ref, int receiver: @object ref); + +fieldstructs(unique int field: @object ref, int struct: @structtype ref); + +methodhosts(int method: @object ref, int host: @namedtype ref); + +defs(int ident: @ident ref, int object: @object ref); + +uses(int ident: @ident ref, int object: @object ref); + +types(unique int id: @type, int kind: int ref); + +type_of(unique int expr: @expr ref, int tp: @type ref); + +typename(unique int tp: @type ref, string name: string ref); + +key_type(unique int map: @maptype ref, int tp: @type ref); + +element_type(unique int container: @containertype ref, int tp: @type ref); + +base_type(unique int ptr: @pointertype ref, int tp: @type ref); + +underlying_type(unique int named: @namedtype ref, int tp: @type ref); + +#keyset[parent, index] +component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref); + +array_length(unique int tp: @arraytype ref, string len: string ref); + +type_objects(unique int tp: @type ref, int object: @object ref); + +packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref); + +#keyset[parent, idx] +modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref); + +#keyset[parent, idx] +modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref); + +#keyset[package, idx] +errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref, + string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref); + +has_ellipsis(int id: @callorconversionexpr ref); + +variadic(int id: @signaturetype ref); + +#keyset[parent, idx] +typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref, + int parent: @typeparamparentobject ref, int idx: int ref); + +@container = @file | @folder; + +@locatable = @xmllocatable | @node | @localscope; + +@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent + | @scopenode | @comment_group | @comment; + +@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr; + +@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec; + +@modexprparent = @file | @modexpr; + +@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr; + +@stmtparent = @funcdef | @stmt | @decl; + +@declparent = @file | @declstmt; + +@typeparamdeclparent = @funcdecl | @typespec; + +@funcdef = @funclit | @funcdecl; + +@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt; + +@location = @location_default; + +@sourceline = @locatable; + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment; + +case @expr.kind of + 0 = @badexpr +| 1 = @ident +| 2 = @ellipsis +| 3 = @intlit +| 4 = @floatlit +| 5 = @imaglit +| 6 = @charlit +| 7 = @stringlit +| 8 = @funclit +| 9 = @compositelit +| 10 = @parenexpr +| 11 = @selectorexpr +| 12 = @indexexpr +| 13 = @genericfunctioninstantiationexpr +| 14 = @generictypeinstantiationexpr +| 15 = @sliceexpr +| 16 = @typeassertexpr +| 17 = @callorconversionexpr +| 18 = @starexpr +| 19 = @keyvalueexpr +| 20 = @arraytypeexpr +| 21 = @structtypeexpr +| 22 = @functypeexpr +| 23 = @interfacetypeexpr +| 24 = @maptypeexpr +| 25 = @typesetliteralexpr +| 26 = @plusexpr +| 27 = @minusexpr +| 28 = @notexpr +| 29 = @complementexpr +| 30 = @derefexpr +| 31 = @addressexpr +| 32 = @arrowexpr +| 33 = @lorexpr +| 34 = @landexpr +| 35 = @eqlexpr +| 36 = @neqexpr +| 37 = @lssexpr +| 38 = @leqexpr +| 39 = @gtrexpr +| 40 = @geqexpr +| 41 = @addexpr +| 42 = @subexpr +| 43 = @orexpr +| 44 = @xorexpr +| 45 = @mulexpr +| 46 = @quoexpr +| 47 = @remexpr +| 48 = @shlexpr +| 49 = @shrexpr +| 50 = @andexpr +| 51 = @andnotexpr +| 52 = @sendchantypeexpr +| 53 = @recvchantypeexpr +| 54 = @sendrcvchantypeexpr +| 55 = @errorexpr; + +@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit; + +@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr; + +@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr; + +@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr; + +@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr; + +@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr; + +@logicalunaryexpr = @notexpr; + +@bitwiseunaryexpr = @complementexpr; + +@arithmeticunaryexpr = @plusexpr | @minusexpr; + +@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison; + +@logicalbinaryexpr = @lorexpr | @landexpr; + +@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr; + +@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr; + +@shiftexpr = @shlexpr | @shrexpr; + +@comparison = @equalitytest | @relationalcomparison; + +@equalitytest = @eqlexpr | @neqexpr; + +@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr; + +@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr; + +case @stmt.kind of + 0 = @badstmt +| 1 = @declstmt +| 2 = @emptystmt +| 3 = @labeledstmt +| 4 = @exprstmt +| 5 = @sendstmt +| 6 = @incstmt +| 7 = @decstmt +| 8 = @gostmt +| 9 = @deferstmt +| 10 = @returnstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @gotostmt +| 14 = @fallthroughstmt +| 15 = @blockstmt +| 16 = @ifstmt +| 17 = @caseclause +| 18 = @exprswitchstmt +| 19 = @typeswitchstmt +| 20 = @commclause +| 21 = @selectstmt +| 22 = @forstmt +| 23 = @rangestmt +| 24 = @assignstmt +| 25 = @definestmt +| 26 = @addassignstmt +| 27 = @subassignstmt +| 28 = @mulassignstmt +| 29 = @quoassignstmt +| 30 = @remassignstmt +| 31 = @andassignstmt +| 32 = @orassignstmt +| 33 = @xorassignstmt +| 34 = @shlassignstmt +| 35 = @shrassignstmt +| 36 = @andnotassignstmt; + +@incdecstmt = @incstmt | @decstmt; + +@assignment = @simpleassignstmt | @compoundassignstmt; + +@simpleassignstmt = @assignstmt | @definestmt; + +@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt + | @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt; + +@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt; + +@switchstmt = @exprswitchstmt | @typeswitchstmt; + +@loopstmt = @forstmt | @rangestmt; + +case @decl.kind of + 0 = @baddecl +| 1 = @importdecl +| 2 = @constdecl +| 3 = @typedecl +| 4 = @vardecl +| 5 = @funcdecl; + +@gendecl = @importdecl | @constdecl | @typedecl | @vardecl; + +case @spec.kind of + 0 = @importspec +| 1 = @valuespec +| 2 = @typedefspec +| 3 = @aliasspec; + +@typespec = @typedefspec | @aliasspec; + +case @object.kind of + 0 = @pkgobject +| 1 = @decltypeobject +| 2 = @builtintypeobject +| 3 = @declconstobject +| 4 = @builtinconstobject +| 5 = @declvarobject +| 6 = @declfunctionobject +| 7 = @builtinfunctionobject +| 8 = @labelobject; + +@typeparamparentobject = @decltypeobject | @declfunctionobject; + +@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject; + +@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject; + +@typeobject = @decltypeobject | @builtintypeobject; + +@valueobject = @constobject | @varobject | @functionobject; + +@constobject = @declconstobject | @builtinconstobject; + +@varobject = @declvarobject; + +@functionobject = @declfunctionobject | @builtinfunctionobject; + +case @scope.kind of + 0 = @universescope +| 1 = @packagescope +| 2 = @localscope; + +case @type.kind of + 0 = @invalidtype +| 1 = @boolexprtype +| 2 = @inttype +| 3 = @int8type +| 4 = @int16type +| 5 = @int32type +| 6 = @int64type +| 7 = @uinttype +| 8 = @uint8type +| 9 = @uint16type +| 10 = @uint32type +| 11 = @uint64type +| 12 = @uintptrtype +| 13 = @float32type +| 14 = @float64type +| 15 = @complex64type +| 16 = @complex128type +| 17 = @stringexprtype +| 18 = @unsafepointertype +| 19 = @boolliteraltype +| 20 = @intliteraltype +| 21 = @runeliteraltype +| 22 = @floatliteraltype +| 23 = @complexliteraltype +| 24 = @stringliteraltype +| 25 = @nilliteraltype +| 26 = @typeparamtype +| 27 = @arraytype +| 28 = @slicetype +| 29 = @structtype +| 30 = @pointertype +| 31 = @interfacetype +| 32 = @tupletype +| 33 = @signaturetype +| 34 = @maptype +| 35 = @sendchantype +| 36 = @recvchantype +| 37 = @sendrcvchantype +| 38 = @namedtype +| 39 = @typesetliteraltype; + +@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype; + +@booltype = @boolexprtype | @boolliteraltype; + +@numerictype = @integertype | @floattype | @complextype; + +@integertype = @signedintegertype | @unsignedintegertype; + +@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype; + +@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype; + +@floattype = @float32type | @float64type | @floatliteraltype; + +@complextype = @complex64type | @complex128type | @complexliteraltype; + +@stringtype = @stringexprtype | @stringliteraltype; + +@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype + | @stringliteraltype | @nilliteraltype; + +@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype + | @signaturetype | @namedtype | @typesetliteraltype; + +@containertype = @arraytype | @slicetype | @maptype | @chantype; + +@chantype = @sendchantype | @recvchantype | @sendrcvchantype; + +case @modexpr.kind of + 0 = @modcommentblock +| 1 = @modline +| 2 = @modlineblock +| 3 = @modlparen +| 4 = @modrparen; + +case @error.kind of + 0 = @unknownerror +| 1 = @listerror +| 2 = @parseerror +| 3 = @typeerror; + diff --git a/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/upgrade.properties b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/upgrade.properties new file mode 100644 index 00000000000..c7242dd66e3 --- /dev/null +++ b/go/ql/lib/upgrades/90fa7836e0a239f69bbebffcf342e92c240d54bc/upgrade.properties @@ -0,0 +1,3 @@ +description: Delete @errorexpr - @badexpr should be used instead +compatibility: full +exprs.rel: run exprs.qlo diff --git a/go/ql/src/AlertSuppression.ql b/go/ql/src/AlertSuppression.ql index f0a3b5df730..d264052bd23 100644 --- a/go/ql/src/AlertSuppression.ql +++ b/go/ql/src/AlertSuppression.ql @@ -49,9 +49,7 @@ class SuppressionComment extends Locatable { /** * The scope of an alert suppression comment. */ -class SuppressionScope extends @locatable { - SuppressionScope() { this instanceof SuppressionComment } - +class SuppressionScope extends @locatable instanceof SuppressionComment { /** Gets a suppression comment with this scope. */ SuppressionComment getSuppressionComment() { result = this } @@ -65,7 +63,7 @@ class SuppressionScope extends @locatable { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) + super.covers(filepath, startline, startcolumn, endline, endcolumn) } /** Gets a textual representation of this element. */ diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 65aa3c40d99..aed077e28d9 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.3.6 + +No user-facing changes. + +## 0.3.5 + +No user-facing changes. + +## 0.3.4 + +No user-facing changes. + ## 0.3.3 ### Minor Analysis Improvements diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index fdd83673b74..29e94f67823 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -83,7 +83,7 @@ predicate regexpGuardsError(RegexpPattern regexp) { class Config extends DataFlow::Configuration { Config() { this = "IncompleteHostNameRegexp::Config" } - predicate isSource(DataFlow::Node source, string hostPart) { + predicate isSourceString(DataFlow::Node source, string hostPart) { exists(Expr e | e = source.asExpr() and isIncompleteHostNameRegexpPattern(e.getStringValue(), hostPart) @@ -95,7 +95,7 @@ class Config extends DataFlow::Configuration { ) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern and @@ -107,7 +107,7 @@ class Config extends DataFlow::Configuration { } from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string hostPart -where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), hostPart) +where c.hasFlowPath(source, sink) and c.isSourceString(source.getNode(), hostPart) select source, source, sink, "This regular expression has an unescaped dot before '" + hostPart + "', " + "so it might match more hosts than expected when $@.", sink, "the regular expression is used" diff --git a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql index 8538e435819..f19bee4b179 100644 --- a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql +++ b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql @@ -63,7 +63,7 @@ predicate isInterestingUnanchoredRegexpString(string re, string msg) { class Config extends DataFlow::Configuration { Config() { this = "MissingRegexpAnchor::Config" } - predicate isSource(DataFlow::Node source, string msg) { + predicate isSourceString(DataFlow::Node source, string msg) { exists(Expr e | e = source.asExpr() | isInterestingUnanchoredRegexpString(e.getStringValue(), msg) or @@ -71,11 +71,11 @@ class Config extends DataFlow::Configuration { ) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern } } from Config c, DataFlow::PathNode source, string msg -where c.hasFlowPath(source, _) and c.isSource(source.getNode(), msg) +where c.hasFlowPath(source, _) and c.isSourceString(source.getNode(), msg) select source.getNode(), msg diff --git a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql index 5c1b4528302..667ab999a34 100644 --- a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql +++ b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql @@ -32,7 +32,7 @@ predicate containsEscapedCharacter(DataFlow::Node source, string character) { class Config extends DataFlow::Configuration { Config() { this = "SuspiciousRegexpEscape" } - predicate isSource(DataFlow::Node source, string report) { + predicate isSourceString(DataFlow::Node source, string report) { containsEscapedCharacter(source, "a") and report = "the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text?" @@ -41,12 +41,12 @@ class Config extends DataFlow::Configuration { report = "a literal backspace \\b; did you mean \\\\b, a word boundary?" } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { isSourceString(source, _) } override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern } } from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report -where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report) +where c.hasFlowPath(source, sink) and c.isSourceString(source.getNode(), report) select source, source, sink, "This string literal that is $@ contains " + report, sink, "used as a regular expression" diff --git a/go/ql/src/Security/CWE-022/ZipSlipGood.go b/go/ql/src/Security/CWE-022/ZipSlipGood.go index 40af79fb999..ac7e37d10de 100644 --- a/go/ql/src/Security/CWE-022/ZipSlipGood.go +++ b/go/ql/src/Security/CWE-022/ZipSlipGood.go @@ -12,7 +12,7 @@ func unzipGood(f string) { for _, f := range r.File { p, _ := filepath.Abs(f.Name) // GOOD: Check that path does not contain ".." before using it - if !strings.Contains(p, "..") { + if !strings.Contains(f.Name, "..") { ioutil.WriteFile(p, []byte("present"), 0666) } } diff --git a/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql b/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql index c52e9c33305..4962a6626fc 100644 --- a/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql +++ b/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql @@ -20,7 +20,7 @@ from DataFlow::Node allocsz where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), allocsz) + cfg.isSinkWithAllocationSize(sink.getNode(), allocsz) select sink, source, sink, "This operation, which is used in an $@, involves a $@ and might overflow.", allocsz, "allocation", source, "potentially large value" diff --git a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql index 452e3b94108..486283ddcb4 100644 --- a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql +++ b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql @@ -66,14 +66,14 @@ class HostKeyCallbackAssignmentConfig extends DataFlow::Configuration { /** * Holds if `sink` is a value written by `write` to a field `ClientConfig.HostKeyCallback`. */ - predicate isSink(DataFlow::Node sink, Write write) { + predicate writeIsSink(DataFlow::Node sink, Write write) { exists(Field f | f.hasQualifiedName(CryptoSsh::packagePath(), "ClientConfig", "HostKeyCallback") and write.writesField(_, f, sink) ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.writeIsSink(sink, _) } } /** @@ -92,8 +92,8 @@ predicate hostCheckReachesSink(DataFlow::PathNode sink) { SsaWithFields sinkAccessPath, SsaWithFields otherSinkAccessPath | config.hasFlowPath(source, otherSink) and - config.isSink(sink.getNode(), sinkWrite) and - config.isSink(otherSink.getNode(), otherSinkWrite) and + config.writeIsSink(sink.getNode(), sinkWrite) and + config.writeIsSink(otherSink.getNode(), otherSinkWrite) and sinkWrite.writesField(sinkAccessPath.getAUse(), _, sink.getNode()) and otherSinkWrite.writesField(otherSinkAccessPath.getAUse(), _, otherSink.getNode()) and otherSinkAccessPath = sinkAccessPath.similar() diff --git a/go/ql/src/Security/CWE-327/InsecureTLS.ql b/go/ql/src/Security/CWE-327/InsecureTLS.ql index f8277226144..9163f767382 100644 --- a/go/ql/src/Security/CWE-327/InsecureTLS.ql +++ b/go/ql/src/Security/CWE-327/InsecureTLS.ql @@ -60,7 +60,7 @@ class TlsVersionFlowConfig extends TaintTracking::Configuration { /** * Holds if `source` is a TLS version source yielding value `val`. */ - predicate isSource(DataFlow::Node source, int val) { + predicate intIsSource(DataFlow::Node source, int val) { val = source.getIntValue() and val = getATlsVersion() and not DataFlow::isReturnedWithError(source) @@ -74,7 +74,7 @@ class TlsVersionFlowConfig extends TaintTracking::Configuration { fieldWrite.writesField(base, fld, sink) } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { intIsSource(source, _) } override predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) } } @@ -87,7 +87,7 @@ predicate secureTlsVersionFlow( ) { exists(int version | config.hasFlowPath(source, sink) and - config.isSource(source.getNode(), version) and + config.intIsSource(source.getNode(), version) and not isInsecureTlsVersion(version, _, fld.getName()) ) } @@ -130,7 +130,7 @@ predicate isInsecureTlsVersionFlow( ) { exists(TlsVersionFlowConfig cfg, int version, Field fld | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), version) and + cfg.intIsSource(source.getNode(), version) and cfg.isSink(sink.getNode(), fld, base, _) and isInsecureTlsVersion(version, _, fld.getName()) and // Exclude cases where a secure TLS version can also flow to the same diff --git a/go/ql/src/Security/CWE-338/InsecureRandomness.ql b/go/ql/src/Security/CWE-338/InsecureRandomness.ql index e87bbbae37b..aa26e171e50 100644 --- a/go/ql/src/Security/CWE-338/InsecureRandomness.ql +++ b/go/ql/src/Security/CWE-338/InsecureRandomness.ql @@ -17,7 +17,7 @@ import DataFlow::PathGraph from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string kind where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), kind) and + cfg.isSinkWithKind(sink.getNode(), kind) and ( kind != "A password-related function" or diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index a35fc03b030..92ac3a9b54f 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -31,7 +31,7 @@ class AuthCodeUrl extends Method { class ConstantStateFlowConf extends DataFlow::Configuration { ConstantStateFlowConf() { this = "ConstantStateFlowConf" } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(AuthCodeUrl m | call = m.getACall() | sink = call.getArgument(0)) } @@ -46,7 +46,7 @@ class ConstantStateFlowConf extends DataFlow::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** @@ -109,11 +109,11 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { any(Fmt::AppenderOrSprinter s).taintStep(pred, succ) } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(AuthCodeUrl m | call = m.getACall() | sink = call.getReceiver()) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** @@ -126,7 +126,7 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) { exists(PrivateUrlFlowsToAuthCodeUrlCall flowConfig, DataFlow::Node receiver | flowConfig.hasFlowTo(receiver) and - flowConfig.isSink(receiver, call) + flowConfig.isSinkCall(receiver, call) ) } @@ -134,7 +134,7 @@ predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) { class FlowToPrint extends DataFlow::Configuration { FlowToPrint() { this = "FlowToPrint" } - predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { + predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { exists(LoggerCall logCall | call = logCall | sink = logCall.getAMessageComponent()) } @@ -142,7 +142,7 @@ class FlowToPrint extends DataFlow::Configuration { source = any(AuthCodeUrl m).getACall().getResult() } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCall(sink, _) } } /** Holds if the provided `CallNode`'s result flows to an argument of a printer call. */ @@ -198,7 +198,7 @@ from DataFlow::CallNode sinkCall where cfg.hasFlowPath(source, sink) and - cfg.isSink(sink.getNode(), sinkCall) and + cfg.isSinkCall(sink.getNode(), sinkCall) and // Exclude cases that seem to be oauth flows done from within a terminal: not seemsLikeDoneWithinATerminal(sinkCall) and not privateUrlFlowsToAuthCodeUrlCall(sinkCall) diff --git a/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp b/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp index b6036f4399b..a592abfff38 100644 --- a/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp +++ b/go/ql/src/Security/CWE-601/BadRedirectCheck.qhelp @@ -7,7 +7,7 @@ Redirect URLs should be checked to ensure that user input cannot cause a site to to arbitrary domains. This is often done with a check that the redirect URL begins with a slash, which most of the time is an absolute redirect on the same host. However, browsers interpret URLs beginning with // or /\ as absolute URLs. For example, a redirect to -//lgtm.com will redirect to https://lgtm.com. Thus, redirect checks must +//example.com will redirect to https://example.com. Thus, redirect checks must also check the second character of redirect URLs.

diff --git a/go/ql/src/Security/CWE-601/BadRedirectCheck.ql b/go/ql/src/Security/CWE-601/BadRedirectCheck.ql index a35d78519bb..9beb2fe160b 100644 --- a/go/ql/src/Security/CWE-601/BadRedirectCheck.ql +++ b/go/ql/src/Security/CWE-601/BadRedirectCheck.ql @@ -94,13 +94,13 @@ predicate urlPath(DataFlow::Node nd) { class Configuration extends TaintTracking::Configuration { Configuration() { this = "BadRedirectCheck" } - override predicate isSource(DataFlow::Node source) { this.isSource(source, _) } + override predicate isSource(DataFlow::Node source) { this.isCheckedSource(source, _) } /** * Holds if `source` is the first node that flows into a use of a variable that is checked by a * bad redirect check `check`.. */ - predicate isSource(DataFlow::Node source, DataFlow::Node check) { + predicate isCheckedSource(DataFlow::Node source, DataFlow::Node check) { exists(SsaWithFields v | DataFlow::localFlow(source, v.getAUse()) and not exists(source.getAPredecessor()) and @@ -170,7 +170,7 @@ predicate isBadRedirectCheckWrapper(DataFlow::Node check, FuncDef f, FunctionInp from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node check where - cfg.isSource(source.getNode(), check) and + cfg.isCheckedSource(source.getNode(), check) and cfg.hasFlowPath(source, sink) select check, source, sink, "This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position.", diff --git a/go/ql/src/Security/CWE-640/EmailInjectionCustomizations.qll b/go/ql/src/Security/CWE-640/EmailInjectionCustomizations.qll index 77e3ad97a3b..1e0d4ee7d4c 100644 --- a/go/ql/src/Security/CWE-640/EmailInjectionCustomizations.qll +++ b/go/ql/src/Security/CWE-640/EmailInjectionCustomizations.qll @@ -17,14 +17,10 @@ module EmailInjection { abstract class Sink extends DataFlow::Node { } /** A source of untrusted data, considered as a taint source for email injection. */ - class UntrustedFlowSourceAsSource extends Source { - UntrustedFlowSourceAsSource() { this instanceof UntrustedFlowSource } - } + class UntrustedFlowSourceAsSource extends Source instanceof UntrustedFlowSource { } /** * A data-flow node that becomes part of an email considered as a taint sink for email injection. */ - class MailDataAsSink extends Sink { - MailDataAsSink() { this instanceof EmailData } - } + class MailDataAsSink extends Sink instanceof EmailData { } } diff --git a/go/ql/src/change-notes/released/0.3.4.md b/go/ql/src/change-notes/released/0.3.4.md new file mode 100644 index 00000000000..5fae94b07c9 --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.4.md @@ -0,0 +1,3 @@ +## 0.3.4 + +No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.3.5.md b/go/ql/src/change-notes/released/0.3.5.md new file mode 100644 index 00000000000..7a86712e637 --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.5.md @@ -0,0 +1,3 @@ +## 0.3.5 + +No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.3.6.md b/go/ql/src/change-notes/released/0.3.6.md new file mode 100644 index 00000000000..0c7a392e88f --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.6.md @@ -0,0 +1,3 @@ +## 0.3.6 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 9da182d3394..7bbaa8987dd 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.3 +lastReleaseVersion: 0.3.6 diff --git a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql index 372b1c21642..9dd62083df4 100644 --- a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql +++ b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql @@ -61,7 +61,7 @@ class FlowsUntrustedToAllowOriginHeader extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } - predicate isSink(DataFlow::Node sink, AllowOriginHeaderWrite hw) { sink = hw.getValue() } + predicate isSinkHW(DataFlow::Node sink, AllowOriginHeaderWrite hw) { sink = hw.getValue() } override predicate isSanitizer(DataFlow::Node node) { exists(ControlFlow::ConditionGuardNode cgn | @@ -71,7 +71,7 @@ class FlowsUntrustedToAllowOriginHeader extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkHW(sink, _) } } /** @@ -95,7 +95,7 @@ predicate allowCredentialsIsSetToTrue(AllowOriginHeaderWrite allowOriginHW) { predicate flowsFromUntrustedToAllowOrigin(AllowOriginHeaderWrite allowOriginHW, string message) { exists(FlowsUntrustedToAllowOriginHeader cfg, DataFlow::Node sink | cfg.hasFlowTo(sink) and - cfg.isSink(sink, allowOriginHW) + cfg.isSinkHW(sink, allowOriginHW) | message = headerAllowOrigin() + " header is set to a user-defined value, and " + @@ -130,9 +130,9 @@ class FlowsFromUntrusted extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } - override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { this.isSinkCgn(sink, _) } - predicate isSink(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn) { + predicate isSinkCgn(DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn) { exists(IfStmt ifs | exists(Expr operand | operand = ifs.getCond().getAChildExpr*() and @@ -171,7 +171,7 @@ class FlowsFromUntrusted extends TaintTracking::Configuration { */ predicate flowsToGuardedByCheckOnUntrusted(AllowOriginHeaderWrite allowOriginHW) { exists(FlowsFromUntrusted cfg, DataFlow::Node sink, ControlFlow::ConditionGuardNode cgn | - cfg.hasFlowTo(sink) and cfg.isSink(sink, cgn) + cfg.hasFlowTo(sink) and cfg.isSinkCgn(sink, cgn) | cgn.dominates(allowOriginHW.getBasicBlock()) ) diff --git a/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql b/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql index cafc719dd7a..3dfc90dc40a 100644 --- a/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql +++ b/go/ql/src/experimental/Unsafe/WrongUsageOfUnsafe.ql @@ -41,16 +41,18 @@ class ConversionToUnsafePointer extends DataFlow::TypeCastNode { class UnsafeTypeCastingConf extends TaintTracking::Configuration { UnsafeTypeCastingConf() { this = "UnsafeTypeCastingConf" } - predicate isSource(DataFlow::Node source, ConversionToUnsafePointer conv) { source = conv } + predicate conversionIsSource(DataFlow::Node source, ConversionToUnsafePointer conv) { + source = conv + } - predicate isSink(DataFlow::Node sink, DataFlow::TypeCastNode ca) { + predicate typeCastNodeIsSink(DataFlow::Node sink, DataFlow::TypeCastNode ca) { ca.getOperand().getType() instanceof UnsafePointerType and sink = ca } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { conversionIsSource(source, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { typeCastNodeIsSink(sink, _) } } /* @@ -66,8 +68,8 @@ predicate castShortArrayToLongerArray( ArrayType arrTo, ArrayType arrFrom, int arrFromSize | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and arrTo = getFinalType(castBig.getResultType()) and ( // Array (whole) to array: @@ -111,8 +113,8 @@ predicate castTypeToArray(DataFlow::PathNode source, DataFlow::PathNode sink, st ArrayType arrTo, Type typeFrom | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and arrTo = getFinalType(castBig.getResultType()) and not typeFrom.getUnderlyingType() instanceof ArrayType and not typeFrom instanceof PointerType and @@ -141,8 +143,8 @@ predicate castDifferentBitSizeNumbers( NumericType numTo, NumericType numFrom | cfg.hasFlowPath(source, sink) and - cfg.isSource(source.getNode(), castLittle) and - cfg.isSink(sink.getNode(), castBig) and + cfg.conversionIsSource(source.getNode(), castLittle) and + cfg.typeCastNodeIsSink(sink.getNode(), castBig) and numTo = getFinalType(castBig.getResultType()) and numFrom = getFinalType(castLittle.getOperand().getType()) and // TODO: also consider cast from uint to int? diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index e44f8ef80d9..88d4e107152 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.4-dev +version: 0.4.0-dev groups: - go - queries diff --git a/go/ql/test/experimental/CWE-090/LDAPInjection.expected b/go/ql/test/experimental/CWE-090/LDAPInjection.expected index 6395227df6e..8e1165fab60 100644 --- a/go/ql/test/experimental/CWE-090/LDAPInjection.expected +++ b/go/ql/test/experimental/CWE-090/LDAPInjection.expected @@ -1,53 +1,53 @@ edges -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:59:3:59:11 | untrusted | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:61:3:61:51 | ...+... | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:62:3:62:33 | slice literal | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:62:24:62:32 | untrusted : string | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:66:3:66:11 | untrusted | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:68:3:68:51 | ...+... | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:69:3:69:33 | slice literal | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:69:24:69:32 | untrusted : string | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:73:3:73:11 | untrusted | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:75:3:75:51 | ...+... | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:76:3:76:33 | slice literal | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:76:24:76:32 | untrusted : string | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:80:22:80:30 | untrusted | -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:81:25:81:33 | untrusted | -| LDAPInjection.go:62:3:62:33 | slice literal [array] : string | LDAPInjection.go:62:3:62:33 | slice literal | -| LDAPInjection.go:62:24:62:32 | untrusted : string | LDAPInjection.go:62:3:62:33 | slice literal [array] : string | -| LDAPInjection.go:69:3:69:33 | slice literal [array] : string | LDAPInjection.go:69:3:69:33 | slice literal | -| LDAPInjection.go:69:24:69:32 | untrusted : string | LDAPInjection.go:69:3:69:33 | slice literal [array] : string | -| LDAPInjection.go:76:3:76:33 | slice literal [array] : string | LDAPInjection.go:76:3:76:33 | slice literal | -| LDAPInjection.go:76:24:76:32 | untrusted : string | LDAPInjection.go:76:3:76:33 | slice literal [array] : string | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:59:3:59:11 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:61:3:61:51 | ...+... | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:62:3:62:33 | slice literal | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:62:24:62:32 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:66:3:66:11 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:68:3:68:51 | ...+... | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:69:3:69:33 | slice literal | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:69:24:69:32 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:73:3:73:11 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:75:3:75:51 | ...+... | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:76:3:76:33 | slice literal | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:76:24:76:32 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:80:22:80:30 | untrusted | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:81:25:81:33 | untrusted | +| LDAPInjection.go:62:3:62:33 | slice literal [array] | LDAPInjection.go:62:3:62:33 | slice literal | +| LDAPInjection.go:62:24:62:32 | untrusted | LDAPInjection.go:62:3:62:33 | slice literal [array] | +| LDAPInjection.go:69:3:69:33 | slice literal [array] | LDAPInjection.go:69:3:69:33 | slice literal | +| LDAPInjection.go:69:24:69:32 | untrusted | LDAPInjection.go:69:3:69:33 | slice literal [array] | +| LDAPInjection.go:76:3:76:33 | slice literal [array] | LDAPInjection.go:76:3:76:33 | slice literal | +| LDAPInjection.go:76:24:76:32 | untrusted | LDAPInjection.go:76:3:76:33 | slice literal [array] | nodes -| LDAPInjection.go:57:15:57:29 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| LDAPInjection.go:57:15:57:29 | call to UserAgent | semmle.label | call to UserAgent | | LDAPInjection.go:59:3:59:11 | untrusted | semmle.label | untrusted | | LDAPInjection.go:61:3:61:51 | ...+... | semmle.label | ...+... | | LDAPInjection.go:62:3:62:33 | slice literal | semmle.label | slice literal | -| LDAPInjection.go:62:3:62:33 | slice literal [array] : string | semmle.label | slice literal [array] : string | -| LDAPInjection.go:62:24:62:32 | untrusted : string | semmle.label | untrusted : string | +| LDAPInjection.go:62:3:62:33 | slice literal [array] | semmle.label | slice literal [array] | +| LDAPInjection.go:62:24:62:32 | untrusted | semmle.label | untrusted | | LDAPInjection.go:66:3:66:11 | untrusted | semmle.label | untrusted | | LDAPInjection.go:68:3:68:51 | ...+... | semmle.label | ...+... | | LDAPInjection.go:69:3:69:33 | slice literal | semmle.label | slice literal | -| LDAPInjection.go:69:3:69:33 | slice literal [array] : string | semmle.label | slice literal [array] : string | -| LDAPInjection.go:69:24:69:32 | untrusted : string | semmle.label | untrusted : string | +| LDAPInjection.go:69:3:69:33 | slice literal [array] | semmle.label | slice literal [array] | +| LDAPInjection.go:69:24:69:32 | untrusted | semmle.label | untrusted | | LDAPInjection.go:73:3:73:11 | untrusted | semmle.label | untrusted | | LDAPInjection.go:75:3:75:51 | ...+... | semmle.label | ...+... | | LDAPInjection.go:76:3:76:33 | slice literal | semmle.label | slice literal | -| LDAPInjection.go:76:3:76:33 | slice literal [array] : string | semmle.label | slice literal [array] : string | -| LDAPInjection.go:76:24:76:32 | untrusted : string | semmle.label | untrusted : string | +| LDAPInjection.go:76:3:76:33 | slice literal [array] | semmle.label | slice literal [array] | +| LDAPInjection.go:76:24:76:32 | untrusted | semmle.label | untrusted | | LDAPInjection.go:80:22:80:30 | untrusted | semmle.label | untrusted | | LDAPInjection.go:81:25:81:33 | untrusted | semmle.label | untrusted | subpaths #select -| LDAPInjection.go:59:3:59:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:59:3:59:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:61:3:61:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:61:3:61:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:62:3:62:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:62:3:62:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:66:3:66:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:66:3:66:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:68:3:68:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:68:3:68:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:69:3:69:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:69:3:69:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:73:3:73:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:73:3:73:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:75:3:75:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:75:3:75:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:76:3:76:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:76:3:76:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:80:22:80:30 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:80:22:80:30 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | -| LDAPInjection.go:81:25:81:33 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent : string | LDAPInjection.go:81:25:81:33 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:59:3:59:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:59:3:59:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:61:3:61:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:61:3:61:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:62:3:62:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:62:3:62:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:66:3:66:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:66:3:66:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:68:3:68:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:68:3:68:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:69:3:69:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:69:3:69:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:73:3:73:11 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:73:3:73:11 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:75:3:75:51 | ...+... | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:75:3:75:51 | ...+... | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:76:3:76:33 | slice literal | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:76:3:76:33 | slice literal | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:80:22:80:30 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:80:22:80:30 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | +| LDAPInjection.go:81:25:81:33 | untrusted | LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:81:25:81:33 | untrusted | LDAP query parameter depends on a $@. | LDAPInjection.go:57:15:57:29 | call to UserAgent | user-provided value | diff --git a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected index 27cc282c58c..1a22c7d1fc3 100644 --- a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected +++ b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected @@ -1,598 +1,598 @@ edges -| CookieWithoutHttpOnly.go:12:10:12:18 | "session" : string | CookieWithoutHttpOnly.go:15:20:15:21 | &... | -| CookieWithoutHttpOnly.go:12:10:12:18 | "session" : string | CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:12:10:12:18 | "session" : string | CookieWithoutHttpOnly.go:15:21:15:21 | c : Cookie | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | CookieWithoutHttpOnly.go:15:20:15:21 | &... | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | CookieWithoutHttpOnly.go:15:21:15:21 | c : Cookie | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:15:20:15:21 | &... | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:15:21:15:21 | c : Cookie | -| CookieWithoutHttpOnly.go:15:21:15:21 | c : Cookie | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:20:13:20:21 | "session" : string | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:20:13:20:21 | "session" : string | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:20:13:20:21 | "session" : string | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | -| CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:29:13:29:21 | "session" : string | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:29:13:29:21 | "session" : string | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:29:13:29:21 | "session" : string | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:31:13:31:16 | true : bool | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:31:13:31:16 | true : bool | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:31:13:31:16 | true : bool | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | -| CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:38:10:38:18 | "session" : string | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:38:10:38:18 | "session" : string | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:38:10:38:18 | "session" : string | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:41:15:41:18 | true : bool | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:41:15:41:18 | true : bool | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:41:15:41:18 | true : bool | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | -| CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:47:10:47:18 | "session" : string | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:47:10:47:18 | "session" : string | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:47:10:47:18 | "session" : string | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:50:15:50:19 | false : bool | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:50:15:50:19 | false : bool | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:50:15:50:19 | false : bool | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | -| CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val : bool | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:55:9:55:13 | false : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:55:9:55:13 | false : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:55:9:55:13 | false : bool | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:57:13:57:21 | "session" : string | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:57:13:57:21 | "session" : string | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:57:13:57:21 | "session" : string | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:59:13:59:15 | val : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:59:13:59:15 | val : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:59:13:59:15 | val : bool | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | -| CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val : bool | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:65:9:65:12 | true : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:65:9:65:12 | true : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:65:9:65:12 | true : bool | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:67:13:67:21 | "session" : string | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:67:13:67:21 | "session" : string | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:67:13:67:21 | "session" : string | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:69:13:69:15 | val : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:69:13:69:15 | val : bool | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:69:13:69:15 | val : bool | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | -| CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val : bool | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:75:9:75:12 | true : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:75:9:75:12 | true : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:75:9:75:12 | true : bool | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:77:10:77:18 | "session" : string | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:77:10:77:18 | "session" : string | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:77:10:77:18 | "session" : string | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:80:15:80:17 | val : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:80:15:80:17 | val : bool | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:80:15:80:17 | val : bool | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | -| CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val : bool | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:85:9:85:13 | false : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:85:9:85:13 | false : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:85:9:85:13 | false : bool | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:87:10:87:18 | "session" : string | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:87:10:87:18 | "session" : string | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:87:10:87:18 | "session" : string | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:90:15:90:17 | val : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:90:15:90:17 | val : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:90:15:90:17 | val : bool | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | -| CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:99:15:99:19 | false : bool | CookieWithoutHttpOnly.go:100:20:100:21 | &... | -| CookieWithoutHttpOnly.go:99:15:99:19 | false : bool | CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:99:15:99:19 | false : bool | CookieWithoutHttpOnly.go:100:21:100:21 | c : Cookie | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | CookieWithoutHttpOnly.go:100:20:100:21 | &... | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | CookieWithoutHttpOnly.go:100:21:100:21 | c : Cookie | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:100:20:100:21 | &... | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:100:21:100:21 | c : Cookie | -| CookieWithoutHttpOnly.go:100:21:100:21 | c : Cookie | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:104:10:104:18 | "session" : string | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:104:10:104:18 | "session" : string | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:104:10:104:18 | "session" : string | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:109:15:109:19 | false : bool | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:109:15:109:19 | false : bool | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:109:15:109:19 | false : bool | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | -| CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" : string | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" : string | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" : string | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:116:10:116:16 | session : string | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:116:10:116:16 | session : string | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:116:10:116:16 | session : string | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:119:15:119:19 | false : bool | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:119:15:119:19 | false : bool | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:119:15:119:19 | false : bool | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | -| CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:126:16:126:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:134:16:134:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:146:16:146:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:158:16:158:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:170:16:170:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type | -| CookieWithoutHttpOnly.go:126:16:126:20 | store : pointer type | CookieWithoutHttpOnly.go:129:2:129:8 | session | -| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:134:16:134:20 | store : pointer type | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal : Options | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal : Options | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal : Options | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly : bool | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly : bool | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly : bool | CookieWithoutHttpOnly.go:142:2:142:8 | session | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:153:2:153:8 | session | -| CookieWithoutHttpOnly.go:146:16:146:20 | store : pointer type | CookieWithoutHttpOnly.go:153:2:153:8 | session | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:153:2:153:8 | session | -| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:153:2:153:8 | session | -| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | CookieWithoutHttpOnly.go:153:2:153:8 | session | -| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:157:14:157:17 | true : bool | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:157:14:157:17 | true : bool | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:157:14:157:17 | true : bool | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:158:16:158:20 | store : pointer type | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal : Options | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal : Options | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal : Options | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly : bool | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly : bool | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly : bool | CookieWithoutHttpOnly.go:166:2:166:8 | session | -| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly : bool | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly : bool | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly : bool | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly : bool | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:170:16:170:20 | store : pointer type | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly : bool | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly : bool | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | -| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly : bool | CookieWithoutHttpOnly.go:178:2:178:8 | session | -| CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type | CookieWithoutHttpOnly.go:191:19:191:25 | session | -| CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type | CookieWithoutHttpOnly.go:202:19:202:25 | session | +| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:15:21:15:21 | c | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:21:15:21 | c | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:21:15:21 | c | +| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | +| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | +| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | +| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | +| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | +| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:65:9:65:12 | true | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:65:9:65:12 | true | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:65:9:65:12 | true | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | +| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:75:9:75:12 | true | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:75:9:75:12 | true | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:75:9:75:12 | true | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | +| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | +| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:100:21:100:21 | c | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:21:100:21 | c | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:21:100:21 | c | +| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | +| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | +| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:126:16:126:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:134:16:134:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:146:16:146:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:158:16:158:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:170:16:170:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:183:16:183:20 | store | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:195:16:195:20 | store | +| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:129:2:129:8 | session | +| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | +| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | +| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:142:2:142:8 | session | +| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | +| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | +| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | +| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:153:2:153:8 | session | +| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | +| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | +| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | +| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | +| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:153:2:153:8 | session | +| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | +| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | +| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:166:2:166:8 | session | +| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | +| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | +| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:178:2:178:8 | session | +| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:191:19:191:25 | session | +| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:202:19:202:25 | session | nodes -| CookieWithoutHttpOnly.go:12:10:12:18 | "session" : string | semmle.label | "session" : string | +| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | semmle.label | "session" | | CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:15:21:15:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:20:13:20:21 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | semmle.label | false : bool | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:15:21:15:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:22:13:22:17 | false | semmle.label | false | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:24:21:24:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:29:13:29:21 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:31:13:31:16 | true : bool | semmle.label | true : bool | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:24:21:24:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:24:21:24:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:31:13:31:16 | true | semmle.label | true | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:33:21:33:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:38:10:38:18 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:41:15:41:18 | true : bool | semmle.label | true : bool | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:33:21:33:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:33:21:33:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:41:15:41:18 | true | semmle.label | true | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:42:21:42:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:47:10:47:18 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:50:15:50:19 | false : bool | semmle.label | false : bool | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:42:21:42:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:42:21:42:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:50:15:50:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:51:21:51:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val : bool | semmle.label | definition of val : bool | -| CookieWithoutHttpOnly.go:55:9:55:13 | false : bool | semmle.label | false : bool | -| CookieWithoutHttpOnly.go:57:13:57:21 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:59:13:59:15 | val : bool | semmle.label | val : bool | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:51:21:51:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:51:21:51:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | semmle.label | definition of val | +| CookieWithoutHttpOnly.go:55:9:55:13 | false | semmle.label | false | +| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:59:13:59:15 | val | semmle.label | val | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:61:21:61:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val : bool | semmle.label | definition of val : bool | -| CookieWithoutHttpOnly.go:65:9:65:12 | true : bool | semmle.label | true : bool | -| CookieWithoutHttpOnly.go:67:13:67:21 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:69:13:69:15 | val : bool | semmle.label | val : bool | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:61:21:61:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:61:21:61:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | semmle.label | definition of val | +| CookieWithoutHttpOnly.go:65:9:65:12 | true | semmle.label | true | +| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:69:13:69:15 | val | semmle.label | val | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:71:21:71:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val : bool | semmle.label | definition of val : bool | -| CookieWithoutHttpOnly.go:75:9:75:12 | true : bool | semmle.label | true : bool | -| CookieWithoutHttpOnly.go:77:10:77:18 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:80:15:80:17 | val : bool | semmle.label | val : bool | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:71:21:71:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:71:21:71:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | semmle.label | definition of val | +| CookieWithoutHttpOnly.go:75:9:75:12 | true | semmle.label | true | +| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:80:15:80:17 | val | semmle.label | val | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:81:21:81:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val : bool | semmle.label | definition of val : bool | -| CookieWithoutHttpOnly.go:85:9:85:13 | false : bool | semmle.label | false : bool | -| CookieWithoutHttpOnly.go:87:10:87:18 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:90:15:90:17 | val : bool | semmle.label | val : bool | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:81:21:81:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:81:21:81:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | semmle.label | definition of val | +| CookieWithoutHttpOnly.go:85:9:85:13 | false | semmle.label | false | +| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:90:15:90:17 | val | semmle.label | val | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:91:21:91:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:99:15:99:19 | false : bool | semmle.label | false : bool | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:91:21:91:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:91:21:91:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:99:15:99:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:100:20:100:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:100:21:100:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:104:10:104:18 | "session" : string | semmle.label | "session" : string | -| CookieWithoutHttpOnly.go:109:15:109:19 | false : bool | semmle.label | false : bool | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:100:21:100:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | semmle.label | "session" | +| CookieWithoutHttpOnly.go:109:15:109:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:110:21:110:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" : string | semmle.label | "login_name" : string | -| CookieWithoutHttpOnly.go:116:10:116:16 | session : string | semmle.label | session : string | -| CookieWithoutHttpOnly.go:119:15:119:19 | false : bool | semmle.label | false : bool | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:110:21:110:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:110:21:110:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | semmle.label | "login_name" | +| CookieWithoutHttpOnly.go:116:10:116:16 | session | semmle.label | session | +| CookieWithoutHttpOnly.go:119:15:119:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... : pointer type | semmle.label | &... : pointer type | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] : Cookie | semmle.label | &... [pointer] : Cookie | -| CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:120:21:120:21 | c : Cookie | semmle.label | c : Cookie | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | semmle.label | call to NewCookieStore : pointer type | -| CookieWithoutHttpOnly.go:126:16:126:20 | store : pointer type | semmle.label | store : pointer type | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] | +| CookieWithoutHttpOnly.go:120:21:120:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:120:21:120:21 | c | semmle.label | c | +| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | semmle.label | call to NewCookieStore | +| CookieWithoutHttpOnly.go:126:16:126:20 | store | semmle.label | store | | CookieWithoutHttpOnly.go:129:2:129:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly : bool | semmle.label | definition of httpOnly : bool | -| CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | semmle.label | false : bool | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:134:16:134:20 | store : pointer type | semmle.label | store : pointer type | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal : Options | semmle.label | struct literal : Options | -| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly : bool | semmle.label | httpOnly : bool | +| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | semmle.label | definition of httpOnly | +| CookieWithoutHttpOnly.go:133:14:133:18 | false | semmle.label | false | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:134:16:134:20 | store | semmle.label | store | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | semmle.label | struct literal | +| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | semmle.label | httpOnly | | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:146:16:146:20 | store : pointer type | semmle.label | store : pointer type | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | semmle.label | struct literal : Options | +| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:146:16:146:20 | store | semmle.label | store | +| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | semmle.label | struct literal | | CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly : bool | semmle.label | definition of httpOnly : bool | -| CookieWithoutHttpOnly.go:157:14:157:17 | true : bool | semmle.label | true : bool | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:158:16:158:20 | store : pointer type | semmle.label | store : pointer type | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal : Options | semmle.label | struct literal : Options | -| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly : bool | semmle.label | httpOnly : bool | +| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | semmle.label | definition of httpOnly | +| CookieWithoutHttpOnly.go:157:14:157:17 | true | semmle.label | true | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:158:16:158:20 | store | semmle.label | store | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | semmle.label | struct literal | +| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | semmle.label | httpOnly | | CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly : bool | semmle.label | argument corresponding to httpOnly : bool | -| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly : bool | semmle.label | definition of httpOnly : bool | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] : Session | semmle.label | definition of session [pointer] : Session | -| CookieWithoutHttpOnly.go:170:16:170:20 | store : pointer type | semmle.label | store : pointer type | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference : Session | semmle.label | implicit dereference : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] : Session | semmle.label | session [pointer] : Session | -| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal : Options | semmle.label | struct literal : Options | -| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly : bool | semmle.label | httpOnly : bool | +| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | semmle.label | argument corresponding to httpOnly | +| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | semmle.label | definition of httpOnly | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | +| CookieWithoutHttpOnly.go:170:16:170:20 | store | semmle.label | store | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | semmle.label | struct literal | +| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | semmle.label | httpOnly | | CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:183:16:183:20 | store : pointer type | semmle.label | store : pointer type | +| CookieWithoutHttpOnly.go:183:16:183:20 | store | semmle.label | store | | CookieWithoutHttpOnly.go:191:19:191:25 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:195:16:195:20 | store : pointer type | semmle.label | store : pointer type | +| CookieWithoutHttpOnly.go:195:16:195:20 | store | semmle.label | store | | CookieWithoutHttpOnly.go:202:19:202:25 | session | semmle.label | session | | CookieWithoutHttpOnly.go:214:66:214:70 | false | semmle.label | false | subpaths #select -| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:12:10:12:18 | "session" : string | CookieWithoutHttpOnly.go:15:20:15:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:22:13:22:17 | false : bool | CookieWithoutHttpOnly.go:24:20:24:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:50:15:50:19 | false : bool | CookieWithoutHttpOnly.go:51:20:51:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:55:9:55:13 | false : bool | CookieWithoutHttpOnly.go:61:20:61:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:85:9:85:13 | false : bool | CookieWithoutHttpOnly.go:91:20:91:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:109:15:109:19 | false : bool | CookieWithoutHttpOnly.go:110:20:110:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:119:15:119:19 | false : bool | CookieWithoutHttpOnly.go:120:20:120:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:129:2:129:8 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:129:2:129:8 | session | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:142:2:142:8 | session | CookieWithoutHttpOnly.go:133:14:133:18 | false : bool | CookieWithoutHttpOnly.go:142:2:142:8 | session | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:153:2:153:8 | session | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal : Options | CookieWithoutHttpOnly.go:153:2:153:8 | session | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:191:19:191:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:191:19:191:25 | session | Cookie attribute 'HttpOnly' is not set to true. | -| CookieWithoutHttpOnly.go:202:19:202:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore : pointer type | CookieWithoutHttpOnly.go:202:19:202:25 | session | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:15:20:15:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:24:20:24:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:51:20:51:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:61:20:61:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:91:20:91:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:110:20:110:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:120:20:120:21 | &... | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:129:2:129:8 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:129:2:129:8 | session | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:142:2:142:8 | session | CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:142:2:142:8 | session | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:153:2:153:8 | session | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:153:2:153:8 | session | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:191:19:191:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:191:19:191:25 | session | Cookie attribute 'HttpOnly' is not set to true. | +| CookieWithoutHttpOnly.go:202:19:202:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:202:19:202:25 | session | Cookie attribute 'HttpOnly' is not set to true. | | CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/go/ql/test/experimental/CWE-321/HardcodedKeys.expected b/go/ql/test/experimental/CWE-321/HardcodedKeys.expected index 23b79ccb2a9..fe0fb2d238d 100644 --- a/go/ql/test/experimental/CWE-321/HardcodedKeys.expected +++ b/go/ql/test/experimental/CWE-321/HardcodedKeys.expected @@ -1,74 +1,74 @@ edges -| HardcodedKeysBad.go:11:18:11:38 | type conversion : string | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | -| HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" : string | HardcodedKeysBad.go:11:18:11:38 | type conversion : string | -| main.go:25:18:25:31 | type conversion : string | main.go:34:28:34:39 | mySigningKey | -| main.go:25:25:25:30 | "key1" : string | main.go:25:18:25:31 | type conversion : string | -| main.go:42:23:42:28 | "key2" : string | main.go:42:16:42:29 | type conversion | -| main.go:60:9:60:22 | type conversion : string | main.go:61:44:61:46 | key | -| main.go:60:16:60:21 | `key3` : string | main.go:60:9:60:22 | type conversion : string | -| main.go:65:9:65:22 | type conversion : string | main.go:66:66:66:68 | key | -| main.go:65:16:65:21 | "key4" : string | main.go:65:9:65:22 | type conversion : string | -| main.go:69:10:69:23 | type conversion : string | main.go:74:15:74:18 | key2 | -| main.go:69:17:69:22 | "key5" : string | main.go:69:10:69:23 | type conversion : string | -| main.go:80:9:80:22 | type conversion : string | main.go:84:41:84:43 | key | -| main.go:80:16:80:21 | "key6" : string | main.go:80:9:80:22 | type conversion : string | -| main.go:89:10:89:23 | type conversion : string | main.go:91:66:91:69 | key2 | -| main.go:89:17:89:22 | "key7" : string | main.go:89:10:89:23 | type conversion : string | -| main.go:97:9:97:22 | type conversion : string | main.go:102:30:102:32 | key | -| main.go:97:16:97:21 | "key8" : string | main.go:97:9:97:22 | type conversion : string | -| main.go:106:15:106:28 | type conversion : string | main.go:107:16:107:24 | sharedKey | -| main.go:106:22:106:27 | "key9" : string | main.go:106:15:106:28 | type conversion : string | -| main.go:110:23:110:37 | type conversion : string | main.go:113:16:113:30 | sharedKeyglobal | -| main.go:110:30:110:36 | "key10" : string | main.go:110:23:110:37 | type conversion : string | -| sanitizer.go:17:9:17:21 | type conversion : string | sanitizer.go:18:44:18:46 | key | -| sanitizer.go:17:16:17:20 | `key` : string | sanitizer.go:17:9:17:21 | type conversion : string | +| HardcodedKeysBad.go:11:18:11:38 | type conversion | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | +| HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | HardcodedKeysBad.go:11:18:11:38 | type conversion | +| main.go:25:18:25:31 | type conversion | main.go:34:28:34:39 | mySigningKey | +| main.go:25:25:25:30 | "key1" | main.go:25:18:25:31 | type conversion | +| main.go:42:23:42:28 | "key2" | main.go:42:16:42:29 | type conversion | +| main.go:60:9:60:22 | type conversion | main.go:61:44:61:46 | key | +| main.go:60:16:60:21 | `key3` | main.go:60:9:60:22 | type conversion | +| main.go:65:9:65:22 | type conversion | main.go:66:66:66:68 | key | +| main.go:65:16:65:21 | "key4" | main.go:65:9:65:22 | type conversion | +| main.go:69:10:69:23 | type conversion | main.go:74:15:74:18 | key2 | +| main.go:69:17:69:22 | "key5" | main.go:69:10:69:23 | type conversion | +| main.go:80:9:80:22 | type conversion | main.go:84:41:84:43 | key | +| main.go:80:16:80:21 | "key6" | main.go:80:9:80:22 | type conversion | +| main.go:89:10:89:23 | type conversion | main.go:91:66:91:69 | key2 | +| main.go:89:17:89:22 | "key7" | main.go:89:10:89:23 | type conversion | +| main.go:97:9:97:22 | type conversion | main.go:102:30:102:32 | key | +| main.go:97:16:97:21 | "key8" | main.go:97:9:97:22 | type conversion | +| main.go:106:15:106:28 | type conversion | main.go:107:16:107:24 | sharedKey | +| main.go:106:22:106:27 | "key9" | main.go:106:15:106:28 | type conversion | +| main.go:110:23:110:37 | type conversion | main.go:113:16:113:30 | sharedKeyglobal | +| main.go:110:30:110:36 | "key10" | main.go:110:23:110:37 | type conversion | +| sanitizer.go:17:9:17:21 | type conversion | sanitizer.go:18:44:18:46 | key | +| sanitizer.go:17:16:17:20 | `key` | sanitizer.go:17:9:17:21 | type conversion | nodes -| HardcodedKeysBad.go:11:18:11:38 | type conversion : string | semmle.label | type conversion : string | -| HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" : string | semmle.label | "AllYourBase" : string | +| HardcodedKeysBad.go:11:18:11:38 | type conversion | semmle.label | type conversion | +| HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | semmle.label | "AllYourBase" | | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | semmle.label | mySigningKey | -| main.go:25:18:25:31 | type conversion : string | semmle.label | type conversion : string | -| main.go:25:25:25:30 | "key1" : string | semmle.label | "key1" : string | +| main.go:25:18:25:31 | type conversion | semmle.label | type conversion | +| main.go:25:25:25:30 | "key1" | semmle.label | "key1" | | main.go:34:28:34:39 | mySigningKey | semmle.label | mySigningKey | | main.go:42:16:42:29 | type conversion | semmle.label | type conversion | -| main.go:42:23:42:28 | "key2" : string | semmle.label | "key2" : string | -| main.go:60:9:60:22 | type conversion : string | semmle.label | type conversion : string | -| main.go:60:16:60:21 | `key3` : string | semmle.label | `key3` : string | +| main.go:42:23:42:28 | "key2" | semmle.label | "key2" | +| main.go:60:9:60:22 | type conversion | semmle.label | type conversion | +| main.go:60:16:60:21 | `key3` | semmle.label | `key3` | | main.go:61:44:61:46 | key | semmle.label | key | -| main.go:65:9:65:22 | type conversion : string | semmle.label | type conversion : string | -| main.go:65:16:65:21 | "key4" : string | semmle.label | "key4" : string | +| main.go:65:9:65:22 | type conversion | semmle.label | type conversion | +| main.go:65:16:65:21 | "key4" | semmle.label | "key4" | | main.go:66:66:66:68 | key | semmle.label | key | -| main.go:69:10:69:23 | type conversion : string | semmle.label | type conversion : string | -| main.go:69:17:69:22 | "key5" : string | semmle.label | "key5" : string | +| main.go:69:10:69:23 | type conversion | semmle.label | type conversion | +| main.go:69:17:69:22 | "key5" | semmle.label | "key5" | | main.go:74:15:74:18 | key2 | semmle.label | key2 | -| main.go:80:9:80:22 | type conversion : string | semmle.label | type conversion : string | -| main.go:80:16:80:21 | "key6" : string | semmle.label | "key6" : string | +| main.go:80:9:80:22 | type conversion | semmle.label | type conversion | +| main.go:80:16:80:21 | "key6" | semmle.label | "key6" | | main.go:84:41:84:43 | key | semmle.label | key | -| main.go:89:10:89:23 | type conversion : string | semmle.label | type conversion : string | -| main.go:89:17:89:22 | "key7" : string | semmle.label | "key7" : string | +| main.go:89:10:89:23 | type conversion | semmle.label | type conversion | +| main.go:89:17:89:22 | "key7" | semmle.label | "key7" | | main.go:91:66:91:69 | key2 | semmle.label | key2 | -| main.go:97:9:97:22 | type conversion : string | semmle.label | type conversion : string | -| main.go:97:16:97:21 | "key8" : string | semmle.label | "key8" : string | +| main.go:97:9:97:22 | type conversion | semmle.label | type conversion | +| main.go:97:16:97:21 | "key8" | semmle.label | "key8" | | main.go:102:30:102:32 | key | semmle.label | key | -| main.go:106:15:106:28 | type conversion : string | semmle.label | type conversion : string | -| main.go:106:22:106:27 | "key9" : string | semmle.label | "key9" : string | +| main.go:106:15:106:28 | type conversion | semmle.label | type conversion | +| main.go:106:22:106:27 | "key9" | semmle.label | "key9" | | main.go:107:16:107:24 | sharedKey | semmle.label | sharedKey | -| main.go:110:23:110:37 | type conversion : string | semmle.label | type conversion : string | -| main.go:110:30:110:36 | "key10" : string | semmle.label | "key10" : string | +| main.go:110:23:110:37 | type conversion | semmle.label | type conversion | +| main.go:110:30:110:36 | "key10" | semmle.label | "key10" | | main.go:113:16:113:30 | sharedKeyglobal | semmle.label | sharedKeyglobal | -| sanitizer.go:17:9:17:21 | type conversion : string | semmle.label | type conversion : string | -| sanitizer.go:17:16:17:20 | `key` : string | semmle.label | `key` : string | +| sanitizer.go:17:9:17:21 | type conversion | semmle.label | type conversion | +| sanitizer.go:17:16:17:20 | `key` | semmle.label | `key` | | sanitizer.go:18:44:18:46 | key | semmle.label | key | subpaths #select -| HardcodedKeysBad.go:19:28:19:39 | mySigningKey | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" : string | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | $@ is used to sign a JWT token. | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | Hardcoded String | -| main.go:34:28:34:39 | mySigningKey | main.go:25:25:25:30 | "key1" : string | main.go:34:28:34:39 | mySigningKey | $@ is used to sign a JWT token. | main.go:25:25:25:30 | "key1" | Hardcoded String | -| main.go:42:16:42:29 | type conversion | main.go:42:23:42:28 | "key2" : string | main.go:42:16:42:29 | type conversion | $@ is used to sign a JWT token. | main.go:42:23:42:28 | "key2" | Hardcoded String | -| main.go:61:44:61:46 | key | main.go:60:16:60:21 | `key3` : string | main.go:61:44:61:46 | key | $@ is used to sign a JWT token. | main.go:60:16:60:21 | `key3` | Hardcoded String | -| main.go:66:66:66:68 | key | main.go:65:16:65:21 | "key4" : string | main.go:66:66:66:68 | key | $@ is used to sign a JWT token. | main.go:65:16:65:21 | "key4" | Hardcoded String | -| main.go:74:15:74:18 | key2 | main.go:69:17:69:22 | "key5" : string | main.go:74:15:74:18 | key2 | $@ is used to sign a JWT token. | main.go:69:17:69:22 | "key5" | Hardcoded String | -| main.go:84:41:84:43 | key | main.go:80:16:80:21 | "key6" : string | main.go:84:41:84:43 | key | $@ is used to sign a JWT token. | main.go:80:16:80:21 | "key6" | Hardcoded String | -| main.go:91:66:91:69 | key2 | main.go:89:17:89:22 | "key7" : string | main.go:91:66:91:69 | key2 | $@ is used to sign a JWT token. | main.go:89:17:89:22 | "key7" | Hardcoded String | -| main.go:102:30:102:32 | key | main.go:97:16:97:21 | "key8" : string | main.go:102:30:102:32 | key | $@ is used to sign a JWT token. | main.go:97:16:97:21 | "key8" | Hardcoded String | -| main.go:107:16:107:24 | sharedKey | main.go:106:22:106:27 | "key9" : string | main.go:107:16:107:24 | sharedKey | $@ is used to sign a JWT token. | main.go:106:22:106:27 | "key9" | Hardcoded String | -| main.go:113:16:113:30 | sharedKeyglobal | main.go:110:30:110:36 | "key10" : string | main.go:113:16:113:30 | sharedKeyglobal | $@ is used to sign a JWT token. | main.go:110:30:110:36 | "key10" | Hardcoded String | -| sanitizer.go:18:44:18:46 | key | sanitizer.go:17:16:17:20 | `key` : string | sanitizer.go:18:44:18:46 | key | $@ is used to sign a JWT token. | sanitizer.go:17:16:17:20 | `key` | Hardcoded String | +| HardcodedKeysBad.go:19:28:19:39 | mySigningKey | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | HardcodedKeysBad.go:19:28:19:39 | mySigningKey | $@ is used to sign a JWT token. | HardcodedKeysBad.go:11:25:11:37 | "AllYourBase" | Hardcoded String | +| main.go:34:28:34:39 | mySigningKey | main.go:25:25:25:30 | "key1" | main.go:34:28:34:39 | mySigningKey | $@ is used to sign a JWT token. | main.go:25:25:25:30 | "key1" | Hardcoded String | +| main.go:42:16:42:29 | type conversion | main.go:42:23:42:28 | "key2" | main.go:42:16:42:29 | type conversion | $@ is used to sign a JWT token. | main.go:42:23:42:28 | "key2" | Hardcoded String | +| main.go:61:44:61:46 | key | main.go:60:16:60:21 | `key3` | main.go:61:44:61:46 | key | $@ is used to sign a JWT token. | main.go:60:16:60:21 | `key3` | Hardcoded String | +| main.go:66:66:66:68 | key | main.go:65:16:65:21 | "key4" | main.go:66:66:66:68 | key | $@ is used to sign a JWT token. | main.go:65:16:65:21 | "key4" | Hardcoded String | +| main.go:74:15:74:18 | key2 | main.go:69:17:69:22 | "key5" | main.go:74:15:74:18 | key2 | $@ is used to sign a JWT token. | main.go:69:17:69:22 | "key5" | Hardcoded String | +| main.go:84:41:84:43 | key | main.go:80:16:80:21 | "key6" | main.go:84:41:84:43 | key | $@ is used to sign a JWT token. | main.go:80:16:80:21 | "key6" | Hardcoded String | +| main.go:91:66:91:69 | key2 | main.go:89:17:89:22 | "key7" | main.go:91:66:91:69 | key2 | $@ is used to sign a JWT token. | main.go:89:17:89:22 | "key7" | Hardcoded String | +| main.go:102:30:102:32 | key | main.go:97:16:97:21 | "key8" | main.go:102:30:102:32 | key | $@ is used to sign a JWT token. | main.go:97:16:97:21 | "key8" | Hardcoded String | +| main.go:107:16:107:24 | sharedKey | main.go:106:22:106:27 | "key9" | main.go:107:16:107:24 | sharedKey | $@ is used to sign a JWT token. | main.go:106:22:106:27 | "key9" | Hardcoded String | +| main.go:113:16:113:30 | sharedKeyglobal | main.go:110:30:110:36 | "key10" | main.go:113:16:113:30 | sharedKeyglobal | $@ is used to sign a JWT token. | main.go:110:30:110:36 | "key10" | Hardcoded String | +| sanitizer.go:18:44:18:46 | key | sanitizer.go:17:16:17:20 | `key` | sanitizer.go:18:44:18:46 | key | $@ is used to sign a JWT token. | sanitizer.go:17:16:17:20 | `key` | Hardcoded String | diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.expected b/go/ql/test/experimental/CWE-369/DivideByZero.expected index e80e3295c22..081dac5ec37 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.expected +++ b/go/ql/test/experimental/CWE-369/DivideByZero.expected @@ -1,32 +1,32 @@ edges -| DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | -| DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:18:11:18:24 | type conversion : uint8 | -| DivideByZero.go:18:11:18:24 | type conversion : uint8 | DivideByZero.go:19:16:19:20 | value | -| DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | -| DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | -| DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | -| DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:55:11:55:24 | type conversion : uint8 | -| DivideByZero.go:55:11:55:24 | type conversion : uint8 | DivideByZero.go:57:17:57:21 | value | +| DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:12:16:12:20 | value | +| DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:18:11:18:24 | type conversion | +| DivideByZero.go:18:11:18:24 | type conversion | DivideByZero.go:19:16:19:20 | value | +| DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:26:16:26:20 | value | +| DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:33:16:33:20 | value | +| DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:40:16:40:20 | value | +| DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:55:11:55:24 | type conversion | +| DivideByZero.go:55:11:55:24 | type conversion | DivideByZero.go:57:17:57:21 | value | nodes -| DivideByZero.go:10:12:10:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| DivideByZero.go:10:12:10:16 | selection of URL | semmle.label | selection of URL | | DivideByZero.go:12:16:12:20 | value | semmle.label | value | -| DivideByZero.go:17:12:17:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| DivideByZero.go:18:11:18:24 | type conversion : uint8 | semmle.label | type conversion : uint8 | +| DivideByZero.go:17:12:17:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:18:11:18:24 | type conversion | semmle.label | type conversion | | DivideByZero.go:19:16:19:20 | value | semmle.label | value | -| DivideByZero.go:24:12:24:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| DivideByZero.go:24:12:24:16 | selection of URL | semmle.label | selection of URL | | DivideByZero.go:26:16:26:20 | value | semmle.label | value | -| DivideByZero.go:31:12:31:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| DivideByZero.go:31:12:31:16 | selection of URL | semmle.label | selection of URL | | DivideByZero.go:33:16:33:20 | value | semmle.label | value | -| DivideByZero.go:38:12:38:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| DivideByZero.go:38:12:38:16 | selection of URL | semmle.label | selection of URL | | DivideByZero.go:40:16:40:20 | value | semmle.label | value | -| DivideByZero.go:54:12:54:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| DivideByZero.go:55:11:55:24 | type conversion : uint8 | semmle.label | type conversion : uint8 | +| DivideByZero.go:54:12:54:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:55:11:55:24 | type conversion | semmle.label | type conversion | | DivideByZero.go:57:17:57:21 | value | semmle.label | value | subpaths #select -| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | This variable might be zero leading to a division-by-zero panic. | -| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | This variable might be zero leading to a division-by-zero panic. | -| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | This variable might be zero leading to a division-by-zero panic. | -| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | This variable might be zero leading to a division-by-zero panic. | -| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | This variable might be zero leading to a division-by-zero panic. | -| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:12:16:12:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:19:16:19:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:26:16:26:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:33:16:33:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:40:16:40:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:57:17:57:21 | value | This variable might be zero leading to a division-by-zero panic. | diff --git a/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected b/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected index ff2053dd942..77cd46d64e6 100644 --- a/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected +++ b/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected @@ -1,117 +1,117 @@ edges -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : string | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | -| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | -| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : string | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | -| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | -| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : string | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | -| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | -| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : string | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | -| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | -| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : string | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | -| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | -| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : string | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | -| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | -| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : string | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | -| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | -| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : string | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | -| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | -| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : string | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | -| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | -| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:75:38:75:44 | escaped | -| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | -| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | -| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | +| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | +| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | +| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | +| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | +| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | +| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | +| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | +| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | +| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | +| HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:75:38:75:44 | escaped | +| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | +| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | +| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | nodes | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | semmle.label | a | @@ -121,16 +121,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | semmle.label | a | @@ -140,16 +140,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | semmle.label | a | @@ -159,16 +159,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | semmle.label | a | | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : HTMLAttr | semmle.label | type conversion : HTMLAttr | -| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | semmle.label | c | | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | semmle.label | c | | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | semmle.label | c | @@ -178,16 +178,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | semmle.label | c | | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | semmle.label | c | | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : JS | semmle.label | type conversion : JS | -| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | semmle.label | d | | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | semmle.label | d | | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | semmle.label | d | @@ -197,16 +197,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | semmle.label | d | | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | semmle.label | d | | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : JSStr | semmle.label | type conversion : JSStr | -| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | semmle.label | e | | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | semmle.label | e | | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | semmle.label | e | @@ -216,16 +216,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | semmle.label | e | | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | semmle.label | e | | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : CSS | semmle.label | type conversion : CSS | -| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | semmle.label | b | | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | semmle.label | b | | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | semmle.label | b | @@ -235,16 +235,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | semmle.label | b | | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | semmle.label | b | | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : Srcset | semmle.label | type conversion : Srcset | -| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | semmle.label | f | | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | semmle.label | f | | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | semmle.label | f | @@ -254,16 +254,16 @@ nodes | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | semmle.label | f | | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | semmle.label | f | | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : URL | semmle.label | type conversion : URL | -| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion : string | semmle.label | type conversion : string | -| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | @@ -272,21 +272,21 @@ nodes | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | semmle.label | g | -| HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:75:38:75:44 | escaped | semmle.label | escaped | -| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | semmle.label | call to UserAgent | | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | semmle.label | src | -| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent | semmle.label | call to UserAgent | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | -| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | @@ -296,12 +296,12 @@ nodes | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | subpaths #select -| HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | Data from an $@ will not be auto-escaped because it was $@ to template.HTMLAttr | HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | Data from an $@ will not be auto-escaped because it was $@ to template.JS | HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | Data from an $@ will not be auto-escaped because it was $@ to template.JSStr | HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | Data from an $@ will not be auto-escaped because it was $@ to template.CSS | HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | Data from an $@ will not be auto-escaped because it was $@ to template.Srcset | HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | converted | -| HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | Data from an $@ will not be auto-escaped because it was $@ to template.URL | HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:40:40:40:40 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:39:19:39:33 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:39:9:39:34 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:46:41:46:41 | c | Data from an $@ will not be auto-escaped because it was $@ to template.HTMLAttr | HTMLTemplateEscapingPassthrough.go:45:29:45:43 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:45:11:45:44 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:50:44:50:44 | d | Data from an $@ will not be auto-escaped because it was $@ to template.JS | HTMLTemplateEscapingPassthrough.go:49:23:49:37 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:49:11:49:38 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:54:44:54:44 | e | Data from an $@ will not be auto-escaped because it was $@ to template.JSStr | HTMLTemplateEscapingPassthrough.go:53:26:53:40 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:53:11:53:41 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:58:38:58:38 | b | Data from an $@ will not be auto-escaped because it was $@ to template.CSS | HTMLTemplateEscapingPassthrough.go:57:24:57:38 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:57:11:57:39 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:62:44:62:44 | f | Data from an $@ will not be auto-escaped because it was $@ to template.Srcset | HTMLTemplateEscapingPassthrough.go:61:27:61:41 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:61:11:61:42 | type conversion | converted | +| HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:66:38:66:38 | g | Data from an $@ will not be auto-escaped because it was $@ to template.URL | HTMLTemplateEscapingPassthrough.go:65:24:65:38 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:65:11:65:39 | type conversion | converted | diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index 5fdd1775d3d..6617c2ee474 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -1,74 +1,68 @@ edges -| builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | -| builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | -| builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | -| builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | -| builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | -| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | -| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | -| new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | -| new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | -| new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | -| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | -| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | -| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | -| new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | implicit dereference : URL | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:81:37:81:43 | selection of URL : pointer type | -| new-tests.go:81:37:81:43 | implicit dereference : URL | new-tests.go:82:11:82:46 | ...+... | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | implicit dereference : URL | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:81:37:81:43 | selection of URL : pointer type | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | -| new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | -| new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | +| builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | +| builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | +| builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | +| builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | +| builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | +| new-tests.go:26:26:26:30 | &... | new-tests.go:31:11:31:57 | call to Sprintf | +| new-tests.go:26:26:26:30 | &... | new-tests.go:32:11:32:57 | call to Sprintf | +| new-tests.go:26:26:26:30 | &... | new-tests.go:35:12:35:58 | call to Sprintf | +| new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | +| new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:68:11:68:57 | call to Sprintf | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:69:11:69:57 | call to Sprintf | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:74:12:74:58 | call to Sprintf | +| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:79:11:79:46 | ...+... | +| new-tests.go:81:37:81:43 | selection of URL | new-tests.go:82:11:82:46 | ...+... | +| new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | +| new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | nodes -| builtin.go:19:12:19:34 | call to FormValue : string | semmle.label | call to FormValue : string | +| builtin.go:19:12:19:34 | call to FormValue | semmle.label | call to FormValue | | builtin.go:22:21:22:62 | ...+... | semmle.label | ...+... | -| builtin.go:83:21:83:31 | call to Referer : string | semmle.label | call to Referer : string | +| builtin.go:83:21:83:31 | call to Referer | semmle.label | call to Referer | | builtin.go:88:27:88:40 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:97:21:97:31 | call to Referer : string | semmle.label | call to Referer : string | +| builtin.go:97:21:97:31 | call to Referer | semmle.label | call to Referer | | builtin.go:101:36:101:49 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:111:21:111:31 | call to Referer : string | semmle.label | call to Referer : string | +| builtin.go:111:21:111:31 | call to Referer | semmle.label | call to Referer | | builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:129:21:129:31 | call to Referer : string | semmle.label | call to Referer : string | +| builtin.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | | builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput | -| new-tests.go:26:26:26:30 | &... : pointer type | semmle.label | &... : pointer type | +| new-tests.go:26:26:26:30 | &... | semmle.label | &... | | new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:32:11:32:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:35:12:35:58 | call to Sprintf | semmle.label | call to Sprintf | -| new-tests.go:39:18:39:30 | call to Param : string | semmle.label | call to Param : string | +| new-tests.go:39:18:39:30 | call to Param | semmle.label | call to Param | | new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... | -| new-tests.go:49:18:49:30 | call to Query : string | semmle.label | call to Query : string | +| new-tests.go:49:18:49:30 | call to Query | semmle.label | call to Query | | new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... | -| new-tests.go:62:31:62:38 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| new-tests.go:62:31:62:38 | selection of Body | semmle.label | selection of Body | | new-tests.go:68:11:68:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:69:11:69:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:74:12:74:58 | call to Sprintf | semmle.label | call to Sprintf | -| new-tests.go:78:18:78:24 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| new-tests.go:78:18:78:24 | selection of URL | semmle.label | selection of URL | | new-tests.go:79:11:79:46 | ...+... | semmle.label | ...+... | -| new-tests.go:81:37:81:43 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| new-tests.go:81:37:81:43 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| new-tests.go:81:37:81:43 | selection of URL | semmle.label | selection of URL | | new-tests.go:82:11:82:46 | ...+... | semmle.label | ...+... | -| new-tests.go:86:10:86:20 | call to Vars : map type | semmle.label | call to Vars : map type | +| new-tests.go:86:10:86:20 | call to Vars | semmle.label | call to Vars | | new-tests.go:88:11:88:46 | ...+... | semmle.label | ...+... | -| new-tests.go:95:18:95:45 | call to URLParam : string | semmle.label | call to URLParam : string | +| new-tests.go:95:18:95:45 | call to URLParam | semmle.label | call to URLParam | | new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... | subpaths #select -| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. | -| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | -| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. | -| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. | -| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value. | -| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value. | -| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. | -| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. | +| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. | +| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | +| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. | diff --git a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected index 277a4b6df90..612c6ef1e51 100644 --- a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected +++ b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected @@ -1,62 +1,62 @@ edges -| WrongUsageOfUnsafe.go:17:24:17:48 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:17:13:17:49 | type conversion | -| WrongUsageOfUnsafe.go:34:24:34:51 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:34:13:34:52 | type conversion | -| WrongUsageOfUnsafe.go:55:24:55:51 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:55:13:55:52 | type conversion | -| WrongUsageOfUnsafe.go:77:27:77:54 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | -| WrongUsageOfUnsafe.go:93:20:93:44 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:93:13:93:45 | type conversion | -| WrongUsageOfUnsafe.go:111:31:111:58 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | -| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | -| WrongUsageOfUnsafe.go:149:31:149:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | -| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | -| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | -| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | -| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:236:21:236:23 | definition of req : unsafe.Pointer | -| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req : unsafe.Pointer | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | -| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | -| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | -| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | +| WrongUsageOfUnsafe.go:17:24:17:48 | type conversion | WrongUsageOfUnsafe.go:17:13:17:49 | type conversion | +| WrongUsageOfUnsafe.go:34:24:34:51 | type conversion | WrongUsageOfUnsafe.go:34:13:34:52 | type conversion | +| WrongUsageOfUnsafe.go:55:24:55:51 | type conversion | WrongUsageOfUnsafe.go:55:13:55:52 | type conversion | +| WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | +| WrongUsageOfUnsafe.go:93:20:93:44 | type conversion | WrongUsageOfUnsafe.go:93:13:93:45 | type conversion | +| WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | +| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | +| WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | +| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | +| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | +| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | +| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | +| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | +| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | +| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | +| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | nodes | WrongUsageOfUnsafe.go:17:13:17:49 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:17:24:17:48 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:17:24:17:48 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:34:13:34:52 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:34:24:34:51 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:34:24:34:51 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:55:13:55:52 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:55:24:55:51 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:55:24:55:51 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:77:27:77:54 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:93:13:93:45 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:93:20:93:44 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:93:20:93:44 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:111:31:111:58 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:149:31:149:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | -| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | -| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req : unsafe.Pointer | semmle.label | definition of req : unsafe.Pointer | +| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | semmle.label | type conversion | +| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | semmle.label | type conversion | +| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | semmle.label | definition of req | | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | semmle.label | type conversion | -| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer | +| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | semmle.label | type conversion | subpaths #select -| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) | -| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) | -| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string | -| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type | -| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 | -| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 | -| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 | +| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) | +| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) | +| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string | +| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type | +| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 | +| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 | +| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected index 24eac7cebc1..bf1bd76aa33 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected @@ -1,59 +1,59 @@ -| generic.go:33:2:33:5 | GetT | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericInterface | GetT | -| generic.go:48:2:48:6 | clone | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | clone | -| generic.go:49:2:49:7 | dummy1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy1 | -| generic.go:50:2:50:7 | dummy2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy2 | -| generic.go:51:2:51:7 | dummy3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy3 | -| generic.go:52:2:52:7 | dummy4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy4 | -| generic.go:53:2:53:7 | dummy5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy5 | -| generic.go:54:2:54:7 | dummy6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy6 | -| generic.go:55:2:55:7 | dummy7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy7 | -| generic.go:56:2:56:8 | dummy11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy11 | -| generic.go:57:2:57:8 | dummy12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy12 | -| generic.go:58:2:58:8 | dummy13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy13 | -| generic.go:59:2:59:8 | dummy14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy14 | -| generic.go:60:2:60:8 | dummy15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy15 | -| generic.go:61:2:61:8 | dummy17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy17 | -| generic.go:62:2:62:8 | dummy18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy18 | -| generic.go:63:2:63:8 | dummy19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy19 | -| generic.go:64:2:64:8 | dummy20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy20 | -| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i6 | String | -| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | String | -| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | String | -| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | String | -| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | String | -| interface.go:37:2:37:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i7 | String | -| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | StringA | -| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | StringA | -| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | StringB | -| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | StringB | -| interface.go:92:2:92:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i17 | StringA | -| interface.go:97:2:97:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i18 | StringA | -| interface.go:102:2:102:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i19 | StringB | -| interface.go:107:2:107:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i20 | StringB | -| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | f | -| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | f | -| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | f | -| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | f | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | g | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | g | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | g | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | g | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder4 | g | -| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | g | -| pkg1/embedding.go:30:18:30:18 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | f | -| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A | m | -| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | m | -| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AEmbedded | m | -| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | m | -| pkg1/interfaces.go:8:2:8:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | m | -| pkg1/interfaces.go:9:2:9:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | n | -| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | n | -| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | n | -| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | o | -| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | o | -| pkg1/interfaces.go:28:2:28:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | n | -| pkg1/interfaces.go:32:2:32:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A2 | m | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half | +| generic.go:33:2:33:5 | GetT | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericInterface | GetT | +| generic.go:48:2:48:6 | clone | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | clone | +| generic.go:49:2:49:7 | dummy1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy1 | +| generic.go:50:2:50:7 | dummy2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy2 | +| generic.go:51:2:51:7 | dummy3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy3 | +| generic.go:52:2:52:7 | dummy4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy4 | +| generic.go:53:2:53:7 | dummy5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy5 | +| generic.go:54:2:54:7 | dummy6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy6 | +| generic.go:55:2:55:7 | dummy7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy7 | +| generic.go:56:2:56:8 | dummy11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy11 | +| generic.go:57:2:57:8 | dummy12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy12 | +| generic.go:58:2:58:8 | dummy13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy13 | +| generic.go:59:2:59:8 | dummy14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy14 | +| generic.go:60:2:60:8 | dummy15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy15 | +| generic.go:61:2:61:8 | dummy17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy17 | +| generic.go:62:2:62:8 | dummy18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy18 | +| generic.go:63:2:63:8 | dummy19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy19 | +| generic.go:64:2:64:8 | dummy20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface | dummy20 | +| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i6 | String | +| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i8 | String | +| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i9 | String | +| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i14 | String | +| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i15 | String | +| interface.go:37:2:37:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i7 | String | +| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i8 | StringA | +| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i14 | StringA | +| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i9 | StringB | +| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i15 | StringB | +| interface.go:92:2:92:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i17 | StringA | +| interface.go:97:2:97:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i18 | StringA | +| interface.go:102:2:102:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i19 | StringB | +| interface.go:107:2:107:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i20 | StringB | +| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base | f | +| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | f | +| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | f | +| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder | f | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base | g | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | g | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | g | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | g | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder4 | g | +| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder | g | +| pkg1/embedding.go:30:18:30:18 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | f | +| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.A | m | +| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AC | m | +| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AEmbedded | m | +| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AExtended | m | +| pkg1/interfaces.go:8:2:8:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.B | m | +| pkg1/interfaces.go:9:2:9:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.B | n | +| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AC | n | +| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.C | n | +| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AC | o | +| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.C | o | +| pkg1/interfaces.go:28:2:28:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.AExtended | n | +| pkg1/interfaces.go:32:2:32:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.A2 | m | +| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half | +| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half | +| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half | +| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.ql b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.ql index b8df1364fc1..e6700d82e47 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.ql +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.ql @@ -1,5 +1,5 @@ import go -from Method meth, string pkg, string tp, string m -where meth.hasQualifiedName(pkg, tp, m) -select meth.getDeclaration(), pkg, tp, m +from Method meth, string tp, string m +where meth.hasQualifiedName(tp, m) +select meth.getDeclaration(), tp, m diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected index f8721f61972..523d27be250 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected @@ -1,22 +1,22 @@ edges -| test.go:9:9:9:11 | selection of c [collection] : string | test.go:9:7:9:11 | <-... | -| test.go:13:16:13:16 | definition of s [pointer, c, collection] : string | test.go:16:2:16:2 | s [pointer, c, collection] : string | -| test.go:15:10:15:17 | call to source : string | test.go:16:9:16:12 | data : string | -| test.go:16:2:16:2 | implicit dereference [c, collection] : string | test.go:13:16:13:16 | definition of s [pointer, c, collection] : string | -| test.go:16:2:16:2 | implicit dereference [c, collection] : string | test.go:16:2:16:4 | selection of c [collection] : string | -| test.go:16:2:16:2 | s [pointer, c, collection] : string | test.go:16:2:16:2 | implicit dereference [c, collection] : string | -| test.go:16:2:16:4 | selection of c [collection] : string | test.go:9:9:9:11 | selection of c [collection] : string | -| test.go:16:2:16:4 | selection of c [collection] : string | test.go:16:2:16:2 | implicit dereference [c, collection] : string | -| test.go:16:9:16:12 | data : string | test.go:16:2:16:4 | selection of c [collection] : string | +| test.go:9:9:9:11 | selection of c [collection] | test.go:9:7:9:11 | <-... | +| test.go:13:16:13:16 | definition of s [pointer, c, collection] | test.go:16:2:16:2 | s [pointer, c, collection] | +| test.go:15:10:15:17 | call to source | test.go:16:9:16:12 | data | +| test.go:16:2:16:2 | implicit dereference [c, collection] | test.go:13:16:13:16 | definition of s [pointer, c, collection] | +| test.go:16:2:16:2 | implicit dereference [c, collection] | test.go:16:2:16:4 | selection of c [collection] | +| test.go:16:2:16:2 | s [pointer, c, collection] | test.go:16:2:16:2 | implicit dereference [c, collection] | +| test.go:16:2:16:4 | selection of c [collection] | test.go:9:9:9:11 | selection of c [collection] | +| test.go:16:2:16:4 | selection of c [collection] | test.go:16:2:16:2 | implicit dereference [c, collection] | +| test.go:16:9:16:12 | data | test.go:16:2:16:4 | selection of c [collection] | nodes | test.go:9:7:9:11 | <-... | semmle.label | <-... | -| test.go:9:9:9:11 | selection of c [collection] : string | semmle.label | selection of c [collection] : string | -| test.go:13:16:13:16 | definition of s [pointer, c, collection] : string | semmle.label | definition of s [pointer, c, collection] : string | -| test.go:15:10:15:17 | call to source : string | semmle.label | call to source : string | -| test.go:16:2:16:2 | implicit dereference [c, collection] : string | semmle.label | implicit dereference [c, collection] : string | -| test.go:16:2:16:2 | s [pointer, c, collection] : string | semmle.label | s [pointer, c, collection] : string | -| test.go:16:2:16:4 | selection of c [collection] : string | semmle.label | selection of c [collection] : string | -| test.go:16:9:16:12 | data : string | semmle.label | data : string | +| test.go:9:9:9:11 | selection of c [collection] | semmle.label | selection of c [collection] | +| test.go:13:16:13:16 | definition of s [pointer, c, collection] | semmle.label | definition of s [pointer, c, collection] | +| test.go:15:10:15:17 | call to source | semmle.label | call to source | +| test.go:16:2:16:2 | implicit dereference [c, collection] | semmle.label | implicit dereference [c, collection] | +| test.go:16:2:16:2 | s [pointer, c, collection] | semmle.label | s [pointer, c, collection] | +| test.go:16:2:16:4 | selection of c [collection] | semmle.label | selection of c [collection] | +| test.go:16:9:16:12 | data | semmle.label | data | subpaths #select -| test.go:15:10:15:17 | call to source : string | test.go:15:10:15:17 | call to source : string | test.go:9:7:9:11 | <-... | path | +| test.go:15:10:15:17 | call to source | test.go:15:10:15:17 | call to source | test.go:9:7:9:11 | <-... | path | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql index 543aecd5d97..c6603c5df93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/steps.ql @@ -22,5 +22,5 @@ class SummaryModelTest extends SummaryModelCsv { } from DataFlow::Node node1, DataFlow::Node node2 -where FlowSummaryImpl::Private::Steps::summaryThroughStep(node1, node2, false) +where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, _) select node1, node2 diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected index cb39cfdd247..37feb5ef6f5 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected @@ -1,317 +1,192 @@ edges -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:29:13:29:30 | type conversion | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:29:20:29:26 | selection of a : slice type | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:30:13:30:27 | type conversion | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:31:13:31:29 | type conversion | -| test.go:27:6:27:10 | definition of bound : bindMe | test.go:31:20:31:26 | selection of c : subBindMe | -| test.go:29:20:29:26 | selection of a : slice type | test.go:29:13:29:30 | type conversion | -| test.go:31:20:31:26 | selection of c : subBindMe | test.go:31:13:31:29 | type conversion | -| test.go:36:20:36:42 | call to Cookie : string | test.go:36:13:36:43 | type conversion | -| test.go:41:20:41:31 | call to Data : map type | test.go:41:13:41:52 | type conversion | -| test.go:46:20:46:43 | call to GetData : basic interface type | test.go:46:13:46:53 | type conversion | -| test.go:51:20:51:42 | call to Header : string | test.go:51:13:51:43 | type conversion | -| test.go:56:20:56:41 | call to Param : string | test.go:56:13:56:42 | type conversion | -| test.go:61:20:61:33 | call to Params : map type | test.go:61:13:61:45 | type conversion | -| test.go:66:20:66:41 | call to Query : string | test.go:66:13:66:42 | type conversion | -| test.go:71:20:71:32 | call to Refer : string | test.go:71:13:71:33 | type conversion | -| test.go:76:20:76:34 | call to Referer : string | test.go:76:13:76:35 | type conversion | -| test.go:81:20:81:30 | call to URI : string | test.go:81:13:81:31 | type conversion | -| test.go:86:20:86:30 | call to URL : string | test.go:86:13:86:31 | type conversion | -| test.go:91:20:91:36 | call to UserAgent : string | test.go:91:13:91:37 | type conversion | -| test.go:96:14:96:25 | call to Data : map type | test.go:96:14:96:45 | type assertion | -| test.go:108:14:108:25 | call to Data : map type | test.go:108:14:108:45 | type assertion | -| test.go:120:14:120:25 | call to Data : map type | test.go:120:14:120:45 | type assertion | -| test.go:137:23:137:42 | call to Data : map type | test.go:137:23:137:62 | type assertion | -| test.go:193:15:193:26 | call to Data : map type | test.go:194:14:194:55 | type conversion | -| test.go:193:15:193:26 | call to Data : map type | test.go:195:14:195:58 | type conversion | -| test.go:193:15:193:26 | call to Data : map type | test.go:197:14:197:28 | type assertion | -| test.go:193:15:193:26 | call to Data : map type | test.go:198:14:198:55 | type conversion | -| test.go:193:15:193:26 | call to Data : map type | test.go:199:14:199:59 | type conversion | -| test.go:202:18:202:33 | selection of Form : Values | test.go:203:14:203:28 | type conversion | -| test.go:217:2:217:34 | ... := ...[0] : File | test.go:220:14:220:20 | content | -| test.go:217:2:217:34 | ... := ...[1] : pointer type | test.go:218:14:218:32 | type conversion | -| test.go:217:2:217:34 | ... := ...[1] : pointer type | test.go:218:21:218:22 | implicit dereference : FileHeader | -| test.go:218:21:218:22 | implicit dereference : FileHeader | test.go:218:14:218:32 | type conversion | -| test.go:218:21:218:22 | implicit dereference : FileHeader | test.go:218:21:218:22 | implicit dereference : FileHeader | -| test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:14:223:38 | type conversion | -| test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:21:223:28 | index expression : pointer type | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:14:223:38 | type conversion | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:223:21:223:28 | implicit dereference : FileHeader | test.go:223:21:223:28 | index expression : pointer type | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:14:223:38 | type conversion | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:21:223:28 | implicit dereference : FileHeader | -| test.go:223:21:223:28 | index expression : pointer type | test.go:223:21:223:28 | index expression : pointer type | -| test.go:225:7:225:28 | call to GetString : string | test.go:226:14:226:22 | type conversion | -| test.go:228:8:228:35 | call to GetStrings : slice type | test.go:229:14:229:26 | type conversion | -| test.go:231:9:231:17 | call to Input : Values | test.go:232:14:232:27 | type conversion | -| test.go:234:6:234:8 | definition of str : myStruct | test.go:236:14:236:30 | type conversion | -| test.go:240:15:240:36 | call to GetString : string | test.go:243:21:243:29 | untrusted | -| test.go:253:23:253:44 | call to GetCookie : string | test.go:253:16:253:45 | type conversion | -| test.go:264:62:264:83 | call to GetCookie : string | test.go:264:55:264:84 | type conversion | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:44:277:51 | index expression : pointer type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:53 | call to SliceChunk : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:56 | index expression : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:60 | call to SliceDiff : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:87 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:96 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:44 | call to SliceFilter : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:71 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:80 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:65 | call to SliceIntersect : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:92 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:65 | call to SliceIntersect : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:92 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:61 | call to SliceMerge : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:88 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:61 | call to SliceMerge : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:88 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:66 | call to SlicePad : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:93 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:66 | call to SlicePad : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:93 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:293:21:293:73 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:293:21:293:82 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:97 | call to SliceReduce : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:124 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:133 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:52 | call to SliceShuffle : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:79 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:88 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:51 | call to SliceUnique : slice type | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:78 | implicit dereference : FileHeader | -| test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:87 | selection of Filename | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:277:44:277:51 | implicit dereference : FileHeader | test.go:277:44:277:51 | index expression : pointer type | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:44:277:51 | implicit dereference : FileHeader | -| test.go:277:44:277:51 | index expression : pointer type | test.go:277:44:277:51 | index expression : pointer type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:56 | index expression : slice type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | -| test.go:278:21:278:53 | call to SliceChunk : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:278:21:278:56 | index expression : slice type | test.go:278:21:278:83 | implicit dereference : FileHeader | -| test.go:278:21:278:56 | index expression : slice type | test.go:278:21:278:92 | selection of Filename | -| test.go:278:21:278:83 | implicit dereference : FileHeader | test.go:278:21:278:92 | selection of Filename | -| test.go:279:21:279:60 | call to SliceDiff : slice type | test.go:279:21:279:87 | implicit dereference : FileHeader | -| test.go:279:21:279:60 | call to SliceDiff : slice type | test.go:279:21:279:96 | selection of Filename | -| test.go:279:21:279:87 | implicit dereference : FileHeader | test.go:279:21:279:96 | selection of Filename | -| test.go:284:3:286:44 | call to SliceFilter : slice type | test.go:284:3:286:71 | implicit dereference : FileHeader | -| test.go:284:3:286:44 | call to SliceFilter : slice type | test.go:284:3:286:80 | selection of Filename | -| test.go:284:3:286:71 | implicit dereference : FileHeader | test.go:284:3:286:80 | selection of Filename | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | test.go:287:21:287:92 | implicit dereference : FileHeader | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | test.go:287:21:287:101 | selection of Filename | -| test.go:287:21:287:92 | implicit dereference : FileHeader | test.go:287:21:287:101 | selection of Filename | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | test.go:288:21:288:92 | implicit dereference : FileHeader | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | test.go:288:21:288:101 | selection of Filename | -| test.go:288:21:288:92 | implicit dereference : FileHeader | test.go:288:21:288:101 | selection of Filename | -| test.go:289:21:289:61 | call to SliceMerge : slice type | test.go:289:21:289:88 | implicit dereference : FileHeader | -| test.go:289:21:289:61 | call to SliceMerge : slice type | test.go:289:21:289:97 | selection of Filename | -| test.go:289:21:289:88 | implicit dereference : FileHeader | test.go:289:21:289:97 | selection of Filename | -| test.go:290:21:290:61 | call to SliceMerge : slice type | test.go:290:21:290:88 | implicit dereference : FileHeader | -| test.go:290:21:290:61 | call to SliceMerge : slice type | test.go:290:21:290:97 | selection of Filename | -| test.go:290:21:290:88 | implicit dereference : FileHeader | test.go:290:21:290:97 | selection of Filename | -| test.go:291:21:291:66 | call to SlicePad : slice type | test.go:291:21:291:93 | implicit dereference : FileHeader | -| test.go:291:21:291:66 | call to SlicePad : slice type | test.go:291:21:291:102 | selection of Filename | -| test.go:291:21:291:93 | implicit dereference : FileHeader | test.go:291:21:291:102 | selection of Filename | -| test.go:292:21:292:66 | call to SlicePad : slice type | test.go:292:21:292:93 | implicit dereference : FileHeader | -| test.go:292:21:292:66 | call to SlicePad : slice type | test.go:292:21:292:102 | selection of Filename | -| test.go:292:21:292:93 | implicit dereference : FileHeader | test.go:292:21:292:102 | selection of Filename | -| test.go:293:21:293:73 | implicit dereference : FileHeader | test.go:293:21:293:82 | selection of Filename | -| test.go:295:21:295:97 | call to SliceReduce : slice type | test.go:295:21:295:124 | implicit dereference : FileHeader | -| test.go:295:21:295:97 | call to SliceReduce : slice type | test.go:295:21:295:133 | selection of Filename | -| test.go:295:21:295:124 | implicit dereference : FileHeader | test.go:295:21:295:133 | selection of Filename | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | test.go:296:21:296:79 | implicit dereference : FileHeader | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | test.go:296:21:296:88 | selection of Filename | -| test.go:296:21:296:79 | implicit dereference : FileHeader | test.go:296:21:296:88 | selection of Filename | -| test.go:297:21:297:51 | call to SliceUnique : slice type | test.go:297:21:297:78 | implicit dereference : FileHeader | -| test.go:297:21:297:51 | call to SliceUnique : slice type | test.go:297:21:297:87 | selection of Filename | -| test.go:297:21:297:78 | implicit dereference : FileHeader | test.go:297:21:297:87 | selection of Filename | -| test.go:303:15:303:36 | call to GetString : string | test.go:305:21:305:48 | type assertion | -| test.go:303:15:303:36 | call to GetString : string | test.go:306:21:306:32 | call to Items : map type | -| test.go:303:15:303:36 | call to GetString : string | test.go:306:21:306:52 | type assertion | -| test.go:306:21:306:32 | call to Items : map type | test.go:306:21:306:52 | type assertion | +| test.go:27:6:27:10 | definition of bound | test.go:29:13:29:30 | type conversion | +| test.go:27:6:27:10 | definition of bound | test.go:30:13:30:27 | type conversion | +| test.go:27:6:27:10 | definition of bound | test.go:31:13:31:29 | type conversion | +| test.go:36:20:36:42 | call to Cookie | test.go:36:13:36:43 | type conversion | +| test.go:41:20:41:31 | call to Data | test.go:41:13:41:52 | type conversion | +| test.go:46:20:46:43 | call to GetData | test.go:46:13:46:53 | type conversion | +| test.go:51:20:51:42 | call to Header | test.go:51:13:51:43 | type conversion | +| test.go:56:20:56:41 | call to Param | test.go:56:13:56:42 | type conversion | +| test.go:61:20:61:33 | call to Params | test.go:61:13:61:45 | type conversion | +| test.go:66:20:66:41 | call to Query | test.go:66:13:66:42 | type conversion | +| test.go:71:20:71:32 | call to Refer | test.go:71:13:71:33 | type conversion | +| test.go:76:20:76:34 | call to Referer | test.go:76:13:76:35 | type conversion | +| test.go:81:20:81:30 | call to URI | test.go:81:13:81:31 | type conversion | +| test.go:86:20:86:30 | call to URL | test.go:86:13:86:31 | type conversion | +| test.go:91:20:91:36 | call to UserAgent | test.go:91:13:91:37 | type conversion | +| test.go:96:14:96:25 | call to Data | test.go:96:14:96:45 | type assertion | +| test.go:108:14:108:25 | call to Data | test.go:108:14:108:45 | type assertion | +| test.go:120:14:120:25 | call to Data | test.go:120:14:120:45 | type assertion | +| test.go:137:23:137:42 | call to Data | test.go:137:23:137:62 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:194:14:194:55 | type conversion | +| test.go:193:15:193:26 | call to Data | test.go:195:14:195:58 | type conversion | +| test.go:193:15:193:26 | call to Data | test.go:197:14:197:28 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:198:14:198:55 | type conversion | +| test.go:193:15:193:26 | call to Data | test.go:199:14:199:59 | type conversion | +| test.go:202:18:202:33 | selection of Form | test.go:203:14:203:28 | type conversion | +| test.go:217:2:217:34 | ... := ...[0] | test.go:220:14:220:20 | content | +| test.go:217:2:217:34 | ... := ...[1] | test.go:218:14:218:32 | type conversion | +| test.go:222:2:222:40 | ... := ...[0] | test.go:223:14:223:38 | type conversion | +| test.go:225:7:225:28 | call to GetString | test.go:226:14:226:22 | type conversion | +| test.go:228:8:228:35 | call to GetStrings | test.go:229:14:229:26 | type conversion | +| test.go:231:9:231:17 | call to Input | test.go:232:14:232:27 | type conversion | +| test.go:234:6:234:8 | definition of str | test.go:236:14:236:30 | type conversion | +| test.go:240:15:240:36 | call to GetString | test.go:243:21:243:29 | untrusted | +| test.go:253:23:253:44 | call to GetCookie | test.go:253:16:253:45 | type conversion | +| test.go:264:62:264:83 | call to GetCookie | test.go:264:55:264:84 | type conversion | +| test.go:269:2:269:40 | ... := ...[0] | test.go:277:21:277:61 | call to GetDisplayString | +| test.go:269:2:269:40 | ... := ...[0] | test.go:278:21:278:92 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:279:21:279:96 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:284:3:286:80 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:287:21:287:101 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:288:21:288:101 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:289:21:289:97 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:290:21:290:97 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:291:21:291:102 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:292:21:292:102 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:293:21:293:82 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:295:21:295:133 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:296:21:296:88 | selection of Filename | +| test.go:269:2:269:40 | ... := ...[0] | test.go:297:21:297:87 | selection of Filename | +| test.go:303:15:303:36 | call to GetString | test.go:305:21:305:48 | type assertion | +| test.go:303:15:303:36 | call to GetString | test.go:306:21:306:52 | type assertion | nodes -| test.go:27:6:27:10 | definition of bound : bindMe | semmle.label | definition of bound : bindMe | +| test.go:27:6:27:10 | definition of bound | semmle.label | definition of bound | | test.go:29:13:29:30 | type conversion | semmle.label | type conversion | -| test.go:29:20:29:26 | selection of a : slice type | semmle.label | selection of a : slice type | | test.go:30:13:30:27 | type conversion | semmle.label | type conversion | | test.go:31:13:31:29 | type conversion | semmle.label | type conversion | -| test.go:31:20:31:26 | selection of c : subBindMe | semmle.label | selection of c : subBindMe | | test.go:36:13:36:43 | type conversion | semmle.label | type conversion | -| test.go:36:20:36:42 | call to Cookie : string | semmle.label | call to Cookie : string | +| test.go:36:20:36:42 | call to Cookie | semmle.label | call to Cookie | | test.go:41:13:41:52 | type conversion | semmle.label | type conversion | -| test.go:41:20:41:31 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:41:20:41:31 | call to Data | semmle.label | call to Data | | test.go:46:13:46:53 | type conversion | semmle.label | type conversion | -| test.go:46:20:46:43 | call to GetData : basic interface type | semmle.label | call to GetData : basic interface type | +| test.go:46:20:46:43 | call to GetData | semmle.label | call to GetData | | test.go:51:13:51:43 | type conversion | semmle.label | type conversion | -| test.go:51:20:51:42 | call to Header : string | semmle.label | call to Header : string | +| test.go:51:20:51:42 | call to Header | semmle.label | call to Header | | test.go:56:13:56:42 | type conversion | semmle.label | type conversion | -| test.go:56:20:56:41 | call to Param : string | semmle.label | call to Param : string | +| test.go:56:20:56:41 | call to Param | semmle.label | call to Param | | test.go:61:13:61:45 | type conversion | semmle.label | type conversion | -| test.go:61:20:61:33 | call to Params : map type | semmle.label | call to Params : map type | +| test.go:61:20:61:33 | call to Params | semmle.label | call to Params | | test.go:66:13:66:42 | type conversion | semmle.label | type conversion | -| test.go:66:20:66:41 | call to Query : string | semmle.label | call to Query : string | +| test.go:66:20:66:41 | call to Query | semmle.label | call to Query | | test.go:71:13:71:33 | type conversion | semmle.label | type conversion | -| test.go:71:20:71:32 | call to Refer : string | semmle.label | call to Refer : string | +| test.go:71:20:71:32 | call to Refer | semmle.label | call to Refer | | test.go:76:13:76:35 | type conversion | semmle.label | type conversion | -| test.go:76:20:76:34 | call to Referer : string | semmle.label | call to Referer : string | +| test.go:76:20:76:34 | call to Referer | semmle.label | call to Referer | | test.go:81:13:81:31 | type conversion | semmle.label | type conversion | -| test.go:81:20:81:30 | call to URI : string | semmle.label | call to URI : string | +| test.go:81:20:81:30 | call to URI | semmle.label | call to URI | | test.go:86:13:86:31 | type conversion | semmle.label | type conversion | -| test.go:86:20:86:30 | call to URL : string | semmle.label | call to URL : string | +| test.go:86:20:86:30 | call to URL | semmle.label | call to URL | | test.go:91:13:91:37 | type conversion | semmle.label | type conversion | -| test.go:91:20:91:36 | call to UserAgent : string | semmle.label | call to UserAgent : string | -| test.go:96:14:96:25 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:91:20:91:36 | call to UserAgent | semmle.label | call to UserAgent | +| test.go:96:14:96:25 | call to Data | semmle.label | call to Data | | test.go:96:14:96:45 | type assertion | semmle.label | type assertion | -| test.go:108:14:108:25 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:108:14:108:25 | call to Data | semmle.label | call to Data | | test.go:108:14:108:45 | type assertion | semmle.label | type assertion | -| test.go:120:14:120:25 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:120:14:120:25 | call to Data | semmle.label | call to Data | | test.go:120:14:120:45 | type assertion | semmle.label | type assertion | -| test.go:137:23:137:42 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:137:23:137:42 | call to Data | semmle.label | call to Data | | test.go:137:23:137:62 | type assertion | semmle.label | type assertion | -| test.go:193:15:193:26 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:193:15:193:26 | call to Data | semmle.label | call to Data | | test.go:194:14:194:55 | type conversion | semmle.label | type conversion | | test.go:195:14:195:58 | type conversion | semmle.label | type conversion | | test.go:197:14:197:28 | type assertion | semmle.label | type assertion | | test.go:198:14:198:55 | type conversion | semmle.label | type conversion | | test.go:199:14:199:59 | type conversion | semmle.label | type conversion | -| test.go:202:18:202:33 | selection of Form : Values | semmle.label | selection of Form : Values | +| test.go:202:18:202:33 | selection of Form | semmle.label | selection of Form | | test.go:203:14:203:28 | type conversion | semmle.label | type conversion | -| test.go:217:2:217:34 | ... := ...[0] : File | semmle.label | ... := ...[0] : File | -| test.go:217:2:217:34 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | +| test.go:217:2:217:34 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:217:2:217:34 | ... := ...[1] | semmle.label | ... := ...[1] | | test.go:218:14:218:32 | type conversion | semmle.label | type conversion | -| test.go:218:21:218:22 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:220:14:220:20 | content | semmle.label | content | -| test.go:222:2:222:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| test.go:222:2:222:40 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:223:14:223:38 | type conversion | semmle.label | type conversion | -| test.go:223:21:223:28 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | -| test.go:223:21:223:28 | index expression : pointer type | semmle.label | index expression : pointer type | -| test.go:225:7:225:28 | call to GetString : string | semmle.label | call to GetString : string | +| test.go:225:7:225:28 | call to GetString | semmle.label | call to GetString | | test.go:226:14:226:22 | type conversion | semmle.label | type conversion | -| test.go:228:8:228:35 | call to GetStrings : slice type | semmle.label | call to GetStrings : slice type | +| test.go:228:8:228:35 | call to GetStrings | semmle.label | call to GetStrings | | test.go:229:14:229:26 | type conversion | semmle.label | type conversion | -| test.go:231:9:231:17 | call to Input : Values | semmle.label | call to Input : Values | +| test.go:231:9:231:17 | call to Input | semmle.label | call to Input | | test.go:232:14:232:27 | type conversion | semmle.label | type conversion | -| test.go:234:6:234:8 | definition of str : myStruct | semmle.label | definition of str : myStruct | +| test.go:234:6:234:8 | definition of str | semmle.label | definition of str | | test.go:236:14:236:30 | type conversion | semmle.label | type conversion | -| test.go:240:15:240:36 | call to GetString : string | semmle.label | call to GetString : string | +| test.go:240:15:240:36 | call to GetString | semmle.label | call to GetString | | test.go:243:21:243:29 | untrusted | semmle.label | untrusted | | test.go:253:16:253:45 | type conversion | semmle.label | type conversion | -| test.go:253:23:253:44 | call to GetCookie : string | semmle.label | call to GetCookie : string | +| test.go:253:23:253:44 | call to GetCookie | semmle.label | call to GetCookie | | test.go:258:16:258:37 | call to GetCookie | semmle.label | call to GetCookie | | test.go:259:15:259:41 | call to GetCookie | semmle.label | call to GetCookie | | test.go:264:55:264:84 | type conversion | semmle.label | type conversion | -| test.go:264:62:264:83 | call to GetCookie : string | semmle.label | call to GetCookie : string | -| test.go:269:2:269:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| test.go:264:62:264:83 | call to GetCookie | semmle.label | call to GetCookie | +| test.go:269:2:269:40 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:277:21:277:61 | call to GetDisplayString | semmle.label | call to GetDisplayString | -| test.go:277:44:277:51 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | -| test.go:277:44:277:51 | index expression : pointer type | semmle.label | index expression : pointer type | -| test.go:278:21:278:53 | call to SliceChunk : slice type | semmle.label | call to SliceChunk : slice type | -| test.go:278:21:278:56 | index expression : slice type | semmle.label | index expression : slice type | -| test.go:278:21:278:83 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:278:21:278:92 | selection of Filename | semmle.label | selection of Filename | -| test.go:279:21:279:60 | call to SliceDiff : slice type | semmle.label | call to SliceDiff : slice type | -| test.go:279:21:279:87 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:279:21:279:96 | selection of Filename | semmle.label | selection of Filename | -| test.go:284:3:286:44 | call to SliceFilter : slice type | semmle.label | call to SliceFilter : slice type | -| test.go:284:3:286:71 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:284:3:286:80 | selection of Filename | semmle.label | selection of Filename | -| test.go:287:21:287:65 | call to SliceIntersect : slice type | semmle.label | call to SliceIntersect : slice type | -| test.go:287:21:287:92 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:287:21:287:101 | selection of Filename | semmle.label | selection of Filename | -| test.go:288:21:288:65 | call to SliceIntersect : slice type | semmle.label | call to SliceIntersect : slice type | -| test.go:288:21:288:92 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:288:21:288:101 | selection of Filename | semmle.label | selection of Filename | -| test.go:289:21:289:61 | call to SliceMerge : slice type | semmle.label | call to SliceMerge : slice type | -| test.go:289:21:289:88 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:289:21:289:97 | selection of Filename | semmle.label | selection of Filename | -| test.go:290:21:290:61 | call to SliceMerge : slice type | semmle.label | call to SliceMerge : slice type | -| test.go:290:21:290:88 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:290:21:290:97 | selection of Filename | semmle.label | selection of Filename | -| test.go:291:21:291:66 | call to SlicePad : slice type | semmle.label | call to SlicePad : slice type | -| test.go:291:21:291:93 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:291:21:291:102 | selection of Filename | semmle.label | selection of Filename | -| test.go:292:21:292:66 | call to SlicePad : slice type | semmle.label | call to SlicePad : slice type | -| test.go:292:21:292:93 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:292:21:292:102 | selection of Filename | semmle.label | selection of Filename | -| test.go:293:21:293:73 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:293:21:293:82 | selection of Filename | semmle.label | selection of Filename | -| test.go:295:21:295:97 | call to SliceReduce : slice type | semmle.label | call to SliceReduce : slice type | -| test.go:295:21:295:124 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:295:21:295:133 | selection of Filename | semmle.label | selection of Filename | -| test.go:296:21:296:52 | call to SliceShuffle : slice type | semmle.label | call to SliceShuffle : slice type | -| test.go:296:21:296:79 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:296:21:296:88 | selection of Filename | semmle.label | selection of Filename | -| test.go:297:21:297:51 | call to SliceUnique : slice type | semmle.label | call to SliceUnique : slice type | -| test.go:297:21:297:78 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | | test.go:297:21:297:87 | selection of Filename | semmle.label | selection of Filename | -| test.go:303:15:303:36 | call to GetString : string | semmle.label | call to GetString : string | +| test.go:303:15:303:36 | call to GetString | semmle.label | call to GetString | | test.go:305:21:305:48 | type assertion | semmle.label | type assertion | -| test.go:306:21:306:32 | call to Items : map type | semmle.label | call to Items : map type | | test.go:306:21:306:52 | type assertion | semmle.label | type assertion | subpaths #select -| test.go:29:13:29:30 | type conversion | test.go:27:6:27:10 | definition of bound : bindMe | test.go:29:13:29:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:30:13:30:27 | type conversion | test.go:27:6:27:10 | definition of bound : bindMe | test.go:30:13:30:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:31:13:31:29 | type conversion | test.go:27:6:27:10 | definition of bound : bindMe | test.go:31:13:31:29 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:36:13:36:43 | type conversion | test.go:36:20:36:42 | call to Cookie : string | test.go:36:13:36:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:36:20:36:42 | call to Cookie | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:41:13:41:52 | type conversion | test.go:41:20:41:31 | call to Data : map type | test.go:41:13:41:52 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:41:20:41:31 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:46:13:46:53 | type conversion | test.go:46:20:46:43 | call to GetData : basic interface type | test.go:46:13:46:53 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:46:20:46:43 | call to GetData | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:51:13:51:43 | type conversion | test.go:51:20:51:42 | call to Header : string | test.go:51:13:51:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:51:20:51:42 | call to Header | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:56:13:56:42 | type conversion | test.go:56:20:56:41 | call to Param : string | test.go:56:13:56:42 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:56:20:56:41 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:61:13:61:45 | type conversion | test.go:61:20:61:33 | call to Params : map type | test.go:61:13:61:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:61:20:61:33 | call to Params | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:66:13:66:42 | type conversion | test.go:66:20:66:41 | call to Query : string | test.go:66:13:66:42 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:66:20:66:41 | call to Query | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:71:13:71:33 | type conversion | test.go:71:20:71:32 | call to Refer : string | test.go:71:13:71:33 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:71:20:71:32 | call to Refer | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:76:13:76:35 | type conversion | test.go:76:20:76:34 | call to Referer : string | test.go:76:13:76:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:76:20:76:34 | call to Referer | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:81:13:81:31 | type conversion | test.go:81:20:81:30 | call to URI : string | test.go:81:13:81:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:81:20:81:30 | call to URI | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:86:13:86:31 | type conversion | test.go:86:20:86:30 | call to URL : string | test.go:86:13:86:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:86:20:86:30 | call to URL | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:91:13:91:37 | type conversion | test.go:91:20:91:36 | call to UserAgent : string | test.go:91:13:91:37 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:91:20:91:36 | call to UserAgent | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:96:14:96:45 | type assertion | test.go:96:14:96:25 | call to Data : map type | test.go:96:14:96:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:96:14:96:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:108:14:108:45 | type assertion | test.go:108:14:108:25 | call to Data : map type | test.go:108:14:108:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:108:14:108:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:120:14:120:45 | type assertion | test.go:120:14:120:25 | call to Data : map type | test.go:120:14:120:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:120:14:120:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:137:23:137:62 | type assertion | test.go:137:23:137:42 | call to Data : map type | test.go:137:23:137:62 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:137:23:137:42 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:194:14:194:55 | type conversion | test.go:193:15:193:26 | call to Data : map type | test.go:194:14:194:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:195:14:195:58 | type conversion | test.go:193:15:193:26 | call to Data : map type | test.go:195:14:195:58 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:197:14:197:28 | type assertion | test.go:193:15:193:26 | call to Data : map type | test.go:197:14:197:28 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:198:14:198:55 | type conversion | test.go:193:15:193:26 | call to Data : map type | test.go:198:14:198:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:199:14:199:59 | type conversion | test.go:193:15:193:26 | call to Data : map type | test.go:199:14:199:59 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:203:14:203:28 | type conversion | test.go:202:18:202:33 | selection of Form : Values | test.go:203:14:203:28 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:202:18:202:33 | selection of Form | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:218:14:218:32 | type conversion | test.go:217:2:217:34 | ... := ...[1] : pointer type | test.go:218:14:218:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:217:2:217:34 | ... := ...[1] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:220:14:220:20 | content | test.go:217:2:217:34 | ... := ...[0] : File | test.go:220:14:220:20 | content | Cross-site scripting vulnerability due to $@. | test.go:217:2:217:34 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:223:14:223:38 | type conversion | test.go:222:2:222:40 | ... := ...[0] : slice type | test.go:223:14:223:38 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:222:2:222:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:226:14:226:22 | type conversion | test.go:225:7:225:28 | call to GetString : string | test.go:226:14:226:22 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:225:7:225:28 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:229:14:229:26 | type conversion | test.go:228:8:228:35 | call to GetStrings : slice type | test.go:229:14:229:26 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:228:8:228:35 | call to GetStrings | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:232:14:232:27 | type conversion | test.go:231:9:231:17 | call to Input : Values | test.go:232:14:232:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:231:9:231:17 | call to Input | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:236:14:236:30 | type conversion | test.go:234:6:234:8 | definition of str : myStruct | test.go:236:14:236:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:234:6:234:8 | definition of str | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:243:21:243:29 | untrusted | test.go:240:15:240:36 | call to GetString : string | test.go:243:21:243:29 | untrusted | Cross-site scripting vulnerability due to $@. | test.go:240:15:240:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:253:16:253:45 | type conversion | test.go:253:23:253:44 | call to GetCookie : string | test.go:253:16:253:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:253:23:253:44 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:29:13:29:30 | type conversion | test.go:27:6:27:10 | definition of bound | test.go:29:13:29:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:30:13:30:27 | type conversion | test.go:27:6:27:10 | definition of bound | test.go:30:13:30:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:31:13:31:29 | type conversion | test.go:27:6:27:10 | definition of bound | test.go:31:13:31:29 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:27:6:27:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:36:13:36:43 | type conversion | test.go:36:20:36:42 | call to Cookie | test.go:36:13:36:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:36:20:36:42 | call to Cookie | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:41:13:41:52 | type conversion | test.go:41:20:41:31 | call to Data | test.go:41:13:41:52 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:41:20:41:31 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:46:13:46:53 | type conversion | test.go:46:20:46:43 | call to GetData | test.go:46:13:46:53 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:46:20:46:43 | call to GetData | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:51:13:51:43 | type conversion | test.go:51:20:51:42 | call to Header | test.go:51:13:51:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:51:20:51:42 | call to Header | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:56:13:56:42 | type conversion | test.go:56:20:56:41 | call to Param | test.go:56:13:56:42 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:56:20:56:41 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:61:13:61:45 | type conversion | test.go:61:20:61:33 | call to Params | test.go:61:13:61:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:61:20:61:33 | call to Params | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:66:13:66:42 | type conversion | test.go:66:20:66:41 | call to Query | test.go:66:13:66:42 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:66:20:66:41 | call to Query | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:71:13:71:33 | type conversion | test.go:71:20:71:32 | call to Refer | test.go:71:13:71:33 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:71:20:71:32 | call to Refer | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:76:13:76:35 | type conversion | test.go:76:20:76:34 | call to Referer | test.go:76:13:76:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:76:20:76:34 | call to Referer | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:81:13:81:31 | type conversion | test.go:81:20:81:30 | call to URI | test.go:81:13:81:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:81:20:81:30 | call to URI | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:86:13:86:31 | type conversion | test.go:86:20:86:30 | call to URL | test.go:86:13:86:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:86:20:86:30 | call to URL | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:91:13:91:37 | type conversion | test.go:91:20:91:36 | call to UserAgent | test.go:91:13:91:37 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:91:20:91:36 | call to UserAgent | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:96:14:96:45 | type assertion | test.go:96:14:96:25 | call to Data | test.go:96:14:96:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:96:14:96:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:108:14:108:45 | type assertion | test.go:108:14:108:25 | call to Data | test.go:108:14:108:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:108:14:108:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:120:14:120:45 | type assertion | test.go:120:14:120:25 | call to Data | test.go:120:14:120:45 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:120:14:120:25 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:137:23:137:62 | type assertion | test.go:137:23:137:42 | call to Data | test.go:137:23:137:62 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:137:23:137:42 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:194:14:194:55 | type conversion | test.go:193:15:193:26 | call to Data | test.go:194:14:194:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:195:14:195:58 | type conversion | test.go:193:15:193:26 | call to Data | test.go:195:14:195:58 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:197:14:197:28 | type assertion | test.go:193:15:193:26 | call to Data | test.go:197:14:197:28 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:198:14:198:55 | type conversion | test.go:193:15:193:26 | call to Data | test.go:198:14:198:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:199:14:199:59 | type conversion | test.go:193:15:193:26 | call to Data | test.go:199:14:199:59 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:193:15:193:26 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:203:14:203:28 | type conversion | test.go:202:18:202:33 | selection of Form | test.go:203:14:203:28 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:202:18:202:33 | selection of Form | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:218:14:218:32 | type conversion | test.go:217:2:217:34 | ... := ...[1] | test.go:218:14:218:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:217:2:217:34 | ... := ...[1] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:220:14:220:20 | content | test.go:217:2:217:34 | ... := ...[0] | test.go:220:14:220:20 | content | Cross-site scripting vulnerability due to $@. | test.go:217:2:217:34 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:223:14:223:38 | type conversion | test.go:222:2:222:40 | ... := ...[0] | test.go:223:14:223:38 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:222:2:222:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:226:14:226:22 | type conversion | test.go:225:7:225:28 | call to GetString | test.go:226:14:226:22 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:225:7:225:28 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:229:14:229:26 | type conversion | test.go:228:8:228:35 | call to GetStrings | test.go:229:14:229:26 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:228:8:228:35 | call to GetStrings | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:232:14:232:27 | type conversion | test.go:231:9:231:17 | call to Input | test.go:232:14:232:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:231:9:231:17 | call to Input | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:236:14:236:30 | type conversion | test.go:234:6:234:8 | definition of str | test.go:236:14:236:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:234:6:234:8 | definition of str | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:243:21:243:29 | untrusted | test.go:240:15:240:36 | call to GetString | test.go:243:21:243:29 | untrusted | Cross-site scripting vulnerability due to $@. | test.go:240:15:240:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:253:16:253:45 | type conversion | test.go:253:23:253:44 | call to GetCookie | test.go:253:16:253:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:253:23:253:44 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:258:16:258:37 | call to GetCookie | test.go:258:16:258:37 | call to GetCookie | test.go:258:16:258:37 | call to GetCookie | Cross-site scripting vulnerability due to $@. | test.go:258:16:258:37 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:259:15:259:41 | call to GetCookie | test.go:259:15:259:41 | call to GetCookie | test.go:259:15:259:41 | call to GetCookie | Cross-site scripting vulnerability due to $@. | test.go:259:15:259:41 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:264:55:264:84 | type conversion | test.go:264:62:264:83 | call to GetCookie : string | test.go:264:55:264:84 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:264:62:264:83 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:277:21:277:61 | call to GetDisplayString | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:277:21:277:61 | call to GetDisplayString | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:278:21:278:92 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:278:21:278:92 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:279:21:279:96 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:279:21:279:96 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:284:3:286:80 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:284:3:286:80 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:287:21:287:101 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:287:21:287:101 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:288:21:288:101 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:288:21:288:101 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:289:21:289:97 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:289:21:289:97 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:290:21:290:97 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:290:21:290:97 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:291:21:291:102 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:291:21:291:102 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:292:21:292:102 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:292:21:292:102 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:293:21:293:82 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:293:21:293:82 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:295:21:295:133 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:295:21:295:133 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:296:21:296:88 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:296:21:296:88 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:297:21:297:87 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] : slice type | test.go:297:21:297:87 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:305:21:305:48 | type assertion | test.go:303:15:303:36 | call to GetString : string | test.go:305:21:305:48 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:303:15:303:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:306:21:306:52 | type assertion | test.go:303:15:303:36 | call to GetString : string | test.go:306:21:306:52 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:303:15:303:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:264:55:264:84 | type conversion | test.go:264:62:264:83 | call to GetCookie | test.go:264:55:264:84 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:264:62:264:83 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:277:21:277:61 | call to GetDisplayString | test.go:269:2:269:40 | ... := ...[0] | test.go:277:21:277:61 | call to GetDisplayString | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:278:21:278:92 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:278:21:278:92 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:279:21:279:96 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:279:21:279:96 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:284:3:286:80 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:284:3:286:80 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:287:21:287:101 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:287:21:287:101 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:288:21:288:101 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:288:21:288:101 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:289:21:289:97 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:289:21:289:97 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:290:21:290:97 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:290:21:290:97 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:291:21:291:102 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:291:21:291:102 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:292:21:292:102 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:292:21:292:102 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:293:21:293:82 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:293:21:293:82 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:295:21:295:133 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:295:21:295:133 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:296:21:296:88 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:296:21:296:88 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:297:21:297:87 | selection of Filename | test.go:269:2:269:40 | ... := ...[0] | test.go:297:21:297:87 | selection of Filename | Cross-site scripting vulnerability due to $@. | test.go:269:2:269:40 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:305:21:305:48 | type assertion | test.go:303:15:303:36 | call to GetString | test.go:305:21:305:48 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:303:15:303:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:306:21:306:52 | type assertion | test.go:303:15:303:36 | call to GetString | test.go:306:21:306:52 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:303:15:303:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected index 116d5d44a6d..a84489df5bc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected @@ -1,18 +1,18 @@ edges -| test.go:209:15:209:26 | call to Data : map type | test.go:210:18:210:26 | untrusted | -| test.go:209:15:209:26 | call to Data : map type | test.go:211:10:211:18 | untrusted | -| test.go:209:15:209:26 | call to Data : map type | test.go:212:35:212:43 | untrusted | -| test.go:318:17:318:37 | selection of RequestBody : slice type | test.go:320:35:320:43 | untrusted | +| test.go:209:15:209:26 | call to Data | test.go:210:18:210:26 | untrusted | +| test.go:209:15:209:26 | call to Data | test.go:211:10:211:18 | untrusted | +| test.go:209:15:209:26 | call to Data | test.go:212:35:212:43 | untrusted | +| test.go:318:17:318:37 | selection of RequestBody | test.go:320:35:320:43 | untrusted | nodes -| test.go:209:15:209:26 | call to Data : map type | semmle.label | call to Data : map type | +| test.go:209:15:209:26 | call to Data | semmle.label | call to Data | | test.go:210:18:210:26 | untrusted | semmle.label | untrusted | | test.go:211:10:211:18 | untrusted | semmle.label | untrusted | | test.go:212:35:212:43 | untrusted | semmle.label | untrusted | -| test.go:318:17:318:37 | selection of RequestBody : slice type | semmle.label | selection of RequestBody : slice type | +| test.go:318:17:318:37 | selection of RequestBody | semmle.label | selection of RequestBody | | test.go:320:35:320:43 | untrusted | semmle.label | untrusted | subpaths #select -| test.go:210:18:210:26 | untrusted | test.go:209:15:209:26 | call to Data : map type | test.go:210:18:210:26 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | -| test.go:211:10:211:18 | untrusted | test.go:209:15:209:26 | call to Data : map type | test.go:211:10:211:18 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | -| test.go:212:35:212:43 | untrusted | test.go:209:15:209:26 | call to Data : map type | test.go:212:35:212:43 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | -| test.go:320:35:320:43 | untrusted | test.go:318:17:318:37 | selection of RequestBody : slice type | test.go:320:35:320:43 | untrusted | This path depends on a $@. | test.go:318:17:318:37 | selection of RequestBody | user-provided value | +| test.go:210:18:210:26 | untrusted | test.go:209:15:209:26 | call to Data | test.go:210:18:210:26 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | +| test.go:211:10:211:18 | untrusted | test.go:209:15:209:26 | call to Data | test.go:211:10:211:18 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | +| test.go:212:35:212:43 | untrusted | test.go:209:15:209:26 | call to Data | test.go:212:35:212:43 | untrusted | This path depends on a $@. | test.go:209:15:209:26 | call to Data | user-provided value | +| test.go:320:35:320:43 | untrusted | test.go:318:17:318:37 | selection of RequestBody | test.go:320:35:320:43 | untrusted | This path depends on a $@. | test.go:318:17:318:37 | selection of RequestBody | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected index 873eed34f41..f9668a6f723 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.expected @@ -1,38 +1,38 @@ edges -| test.go:10:15:10:41 | call to UserAgent : string | test.go:12:11:12:19 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:13:23:13:31 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:14:14:14:22 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:15:26:15:34 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:16:12:16:20 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:17:24:17:32 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:18:15:18:23 | untrusted | -| test.go:10:15:10:41 | call to UserAgent : string | test.go:19:27:19:35 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:26:12:26:20 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:27:10:27:18 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:28:15:28:23 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:29:14:29:22 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:30:15:30:23 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:31:8:31:16 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:32:11:32:19 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:33:9:33:17 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:34:8:34:16 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:35:8:35:16 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:36:13:36:21 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:37:13:37:21 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:38:12:38:20 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:39:12:39:20 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:40:9:40:17 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:41:12:41:20 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:42:16:42:24 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:42:27:42:35 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:43:12:43:20 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:44:14:44:22 | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | test.go:44:25:44:33 | untrusted | -| test.go:48:15:48:41 | call to UserAgent : string | test.go:49:12:49:20 | untrusted | -| test.go:54:15:54:41 | call to UserAgent : string | test.go:56:31:56:39 | untrusted | -| test.go:60:15:60:41 | call to UserAgent : string | test.go:62:19:62:27 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:12:11:12:19 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:13:23:13:31 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:14:14:14:22 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:15:26:15:34 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:16:12:16:20 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:17:24:17:32 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:18:15:18:23 | untrusted | +| test.go:10:15:10:41 | call to UserAgent | test.go:19:27:19:35 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:26:12:26:20 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:27:10:27:18 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:28:15:28:23 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:29:14:29:22 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:31:8:31:16 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:32:11:32:19 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:33:9:33:17 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:34:8:34:16 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:35:8:35:16 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:36:13:36:21 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:37:13:37:21 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:38:12:38:20 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:39:12:39:20 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:40:9:40:17 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:41:12:41:20 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:42:16:42:24 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:42:27:42:35 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:43:12:43:20 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:44:14:44:22 | untrusted | +| test.go:24:15:24:41 | call to UserAgent | test.go:44:25:44:33 | untrusted | +| test.go:48:15:48:41 | call to UserAgent | test.go:49:12:49:20 | untrusted | +| test.go:54:15:54:41 | call to UserAgent | test.go:56:31:56:39 | untrusted | +| test.go:60:15:60:41 | call to UserAgent | test.go:62:19:62:27 | untrusted | nodes -| test.go:10:15:10:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| test.go:10:15:10:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:12:11:12:19 | untrusted | semmle.label | untrusted | | test.go:13:23:13:31 | untrusted | semmle.label | untrusted | | test.go:14:14:14:22 | untrusted | semmle.label | untrusted | @@ -41,7 +41,7 @@ nodes | test.go:17:24:17:32 | untrusted | semmle.label | untrusted | | test.go:18:15:18:23 | untrusted | semmle.label | untrusted | | test.go:19:27:19:35 | untrusted | semmle.label | untrusted | -| test.go:24:15:24:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| test.go:24:15:24:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:26:12:26:20 | untrusted | semmle.label | untrusted | | test.go:27:10:27:18 | untrusted | semmle.label | untrusted | | test.go:28:15:28:23 | untrusted | semmle.label | untrusted | @@ -63,43 +63,43 @@ nodes | test.go:43:12:43:20 | untrusted | semmle.label | untrusted | | test.go:44:14:44:22 | untrusted | semmle.label | untrusted | | test.go:44:25:44:33 | untrusted | semmle.label | untrusted | -| test.go:48:15:48:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| test.go:48:15:48:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:49:12:49:20 | untrusted | semmle.label | untrusted | -| test.go:54:15:54:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| test.go:54:15:54:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:56:31:56:39 | untrusted | semmle.label | untrusted | -| test.go:60:15:60:41 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| test.go:60:15:60:41 | call to UserAgent | semmle.label | call to UserAgent | | test.go:62:19:62:27 | untrusted | semmle.label | untrusted | subpaths #select -| test.go:12:11:12:19 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:12:11:12:19 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:13:23:13:31 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:13:23:13:31 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:14:14:14:22 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:14:14:14:22 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:15:26:15:34 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:15:26:15:34 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:16:12:16:20 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:16:12:16:20 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:17:24:17:32 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:17:24:17:32 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:18:15:18:23 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:18:15:18:23 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:19:27:19:35 | untrusted | test.go:10:15:10:41 | call to UserAgent : string | test.go:19:27:19:35 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | -| test.go:26:12:26:20 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:26:12:26:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:27:10:27:18 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:27:10:27:18 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:28:15:28:23 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:28:15:28:23 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:29:14:29:22 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:29:14:29:22 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:30:15:30:23 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:30:15:30:23 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:31:8:31:16 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:31:8:31:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:32:11:32:19 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:32:11:32:19 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:33:9:33:17 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:33:9:33:17 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:34:8:34:16 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:34:8:34:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:35:8:35:16 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:35:8:35:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:36:13:36:21 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:36:13:36:21 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:37:13:37:21 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:37:13:37:21 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:38:12:38:20 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:38:12:38:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:39:12:39:20 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:39:12:39:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:40:9:40:17 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:40:9:40:17 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:41:12:41:20 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:41:12:41:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:42:16:42:24 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:42:16:42:24 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:42:27:42:35 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:42:27:42:35 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:43:12:43:20 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:43:12:43:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:44:14:44:22 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:44:14:44:22 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:44:25:44:33 | untrusted | test.go:24:15:24:41 | call to UserAgent : string | test.go:44:25:44:33 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | -| test.go:49:12:49:20 | untrusted | test.go:48:15:48:41 | call to UserAgent : string | test.go:49:12:49:20 | untrusted | This query depends on a $@. | test.go:48:15:48:41 | call to UserAgent | user-provided value | -| test.go:56:31:56:39 | untrusted | test.go:54:15:54:41 | call to UserAgent : string | test.go:56:31:56:39 | untrusted | This query depends on a $@. | test.go:54:15:54:41 | call to UserAgent | user-provided value | -| test.go:62:19:62:27 | untrusted | test.go:60:15:60:41 | call to UserAgent : string | test.go:62:19:62:27 | untrusted | This query depends on a $@. | test.go:60:15:60:41 | call to UserAgent | user-provided value | +| test.go:12:11:12:19 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:12:11:12:19 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:13:23:13:31 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:13:23:13:31 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:14:14:14:22 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:14:14:14:22 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:15:26:15:34 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:15:26:15:34 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:16:12:16:20 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:16:12:16:20 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:17:24:17:32 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:17:24:17:32 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:18:15:18:23 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:18:15:18:23 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:19:27:19:35 | untrusted | test.go:10:15:10:41 | call to UserAgent | test.go:19:27:19:35 | untrusted | This query depends on a $@. | test.go:10:15:10:41 | call to UserAgent | user-provided value | +| test.go:26:12:26:20 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:26:12:26:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:27:10:27:18 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:27:10:27:18 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:28:15:28:23 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:28:15:28:23 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:29:14:29:22 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:29:14:29:22 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:30:15:30:23 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:30:15:30:23 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:31:8:31:16 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:31:8:31:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:32:11:32:19 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:32:11:32:19 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:33:9:33:17 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:33:9:33:17 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:34:8:34:16 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:34:8:34:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:35:8:35:16 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:35:8:35:16 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:36:13:36:21 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:36:13:36:21 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:37:13:37:21 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:37:13:37:21 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:38:12:38:20 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:38:12:38:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:39:12:39:20 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:39:12:39:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:40:9:40:17 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:40:9:40:17 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:41:12:41:20 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:41:12:41:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:42:16:42:24 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:42:16:42:24 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:42:27:42:35 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:42:27:42:35 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:43:12:43:20 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:43:12:43:20 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:44:14:44:22 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:44:14:44:22 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:44:25:44:33 | untrusted | test.go:24:15:24:41 | call to UserAgent | test.go:44:25:44:33 | untrusted | This query depends on a $@. | test.go:24:15:24:41 | call to UserAgent | user-provided value | +| test.go:49:12:49:20 | untrusted | test.go:48:15:48:41 | call to UserAgent | test.go:49:12:49:20 | untrusted | This query depends on a $@. | test.go:48:15:48:41 | call to UserAgent | user-provided value | +| test.go:56:31:56:39 | untrusted | test.go:54:15:54:41 | call to UserAgent | test.go:56:31:56:39 | untrusted | This query depends on a $@. | test.go:54:15:54:41 | call to UserAgent | user-provided value | +| test.go:62:19:62:27 | untrusted | test.go:60:15:60:41 | call to UserAgent | test.go:62:19:62:27 | untrusted | This query depends on a $@. | test.go:60:15:60:41 | call to UserAgent | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected index e0d6b678335..09a41c42fb2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected @@ -1,128 +1,111 @@ edges -| test.go:77:13:77:16 | &... : pointer type | test.go:78:13:78:29 | type conversion | -| test.go:77:13:77:16 | &... : pointer type | test.go:79:13:79:43 | type conversion | -| test.go:77:13:77:16 | &... : pointer type | test.go:79:20:79:33 | selection of substructs : slice type | -| test.go:77:13:77:16 | &... : pointer type | test.go:79:20:79:36 | index expression : SubStruct | -| test.go:79:20:79:33 | selection of substructs : slice type | test.go:79:13:79:43 | type conversion | -| test.go:79:20:79:33 | selection of substructs : slice type | test.go:79:20:79:36 | index expression : SubStruct | -| test.go:79:20:79:36 | index expression : SubStruct | test.go:79:13:79:43 | type conversion | -| test.go:82:22:82:26 | &... : pointer type | test.go:83:13:83:30 | type conversion | -| test.go:86:21:86:25 | &... : pointer type | test.go:87:13:87:30 | type conversion | -| test.go:92:20:92:36 | call to Value : string | test.go:92:13:92:37 | type conversion | -| test.go:93:20:93:39 | call to RawValue : basic interface type | test.go:93:13:93:49 | type conversion | -| test.go:94:20:94:37 | call to String : string | test.go:94:13:94:38 | type conversion | -| test.go:95:20:95:36 | call to Value : string | test.go:95:13:95:37 | type conversion | -| test.go:96:20:96:39 | call to RawValue : basic interface type | test.go:96:13:96:49 | type conversion | -| test.go:97:20:97:37 | call to String : string | test.go:97:13:97:38 | type conversion | -| test.go:98:20:98:37 | call to Value : string | test.go:98:13:98:38 | type conversion | -| test.go:99:20:99:40 | call to RawValue : basic interface type | test.go:99:13:99:50 | type conversion | -| test.go:100:20:100:38 | call to String : string | test.go:100:13:100:39 | type conversion | -| test.go:106:9:106:13 | &... : pointer type | test.go:107:13:107:33 | type conversion | -| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | index expression : pointer type | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:13:107:33 | type conversion | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:107:20:107:26 | implicit dereference : MyStruct | test.go:107:20:107:26 | index expression : pointer type | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:13:107:33 | type conversion | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct | -| test.go:107:20:107:26 | index expression : pointer type | test.go:107:20:107:26 | index expression : pointer type | -| test.go:110:9:110:12 | &... : pointer type | test.go:111:13:111:29 | type conversion | -| test.go:114:12:114:19 | &... : pointer type | test.go:115:13:115:48 | type conversion | -| test.go:118:16:118:24 | &... : pointer type | test.go:119:13:119:43 | type conversion | -| test.go:122:16:122:23 | &... : pointer type | test.go:123:13:123:39 | type conversion | -| test.go:126:15:126:24 | &... : pointer type | test.go:127:13:127:47 | type conversion | -| test.go:130:18:130:30 | &... : pointer type | test.go:131:13:131:38 | type conversion | -| test.go:137:12:137:19 | &... : pointer type | test.go:138:13:138:48 | type conversion | -| test.go:141:16:141:24 | &... : pointer type | test.go:142:13:142:43 | type conversion | -| test.go:145:16:145:23 | &... : pointer type | test.go:146:13:146:39 | type conversion | -| test.go:149:15:149:24 | &... : pointer type | test.go:150:13:150:47 | type conversion | -| test.go:153:18:153:30 | &... : pointer type | test.go:154:13:154:38 | type conversion | -| test.go:157:14:157:22 | &... : pointer type | test.go:158:13:158:28 | type conversion | -| test.go:161:15:161:24 | &... : pointer type | test.go:162:13:162:32 | type conversion | +| test.go:77:13:77:16 | &... | test.go:78:13:78:29 | type conversion | +| test.go:77:13:77:16 | &... | test.go:79:13:79:43 | type conversion | +| test.go:82:22:82:26 | &... | test.go:83:13:83:30 | type conversion | +| test.go:86:21:86:25 | &... | test.go:87:13:87:30 | type conversion | +| test.go:92:20:92:36 | call to Value | test.go:92:13:92:37 | type conversion | +| test.go:93:20:93:39 | call to RawValue | test.go:93:13:93:49 | type conversion | +| test.go:94:20:94:37 | call to String | test.go:94:13:94:38 | type conversion | +| test.go:95:20:95:36 | call to Value | test.go:95:13:95:37 | type conversion | +| test.go:96:20:96:39 | call to RawValue | test.go:96:13:96:49 | type conversion | +| test.go:97:20:97:37 | call to String | test.go:97:13:97:38 | type conversion | +| test.go:98:20:98:37 | call to Value | test.go:98:13:98:38 | type conversion | +| test.go:99:20:99:40 | call to RawValue | test.go:99:13:99:50 | type conversion | +| test.go:100:20:100:38 | call to String | test.go:100:13:100:39 | type conversion | +| test.go:106:9:106:13 | &... | test.go:107:13:107:33 | type conversion | +| test.go:110:9:110:12 | &... | test.go:111:13:111:29 | type conversion | +| test.go:114:12:114:19 | &... | test.go:115:13:115:48 | type conversion | +| test.go:118:16:118:24 | &... | test.go:119:13:119:43 | type conversion | +| test.go:122:16:122:23 | &... | test.go:123:13:123:39 | type conversion | +| test.go:126:15:126:24 | &... | test.go:127:13:127:47 | type conversion | +| test.go:130:18:130:30 | &... | test.go:131:13:131:38 | type conversion | +| test.go:137:12:137:19 | &... | test.go:138:13:138:48 | type conversion | +| test.go:141:16:141:24 | &... | test.go:142:13:142:43 | type conversion | +| test.go:145:16:145:23 | &... | test.go:146:13:146:39 | type conversion | +| test.go:149:15:149:24 | &... | test.go:150:13:150:47 | type conversion | +| test.go:153:18:153:30 | &... | test.go:154:13:154:38 | type conversion | +| test.go:157:14:157:22 | &... | test.go:158:13:158:28 | type conversion | +| test.go:161:15:161:24 | &... | test.go:162:13:162:32 | type conversion | nodes -| test.go:77:13:77:16 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:77:13:77:16 | &... | semmle.label | &... | | test.go:78:13:78:29 | type conversion | semmle.label | type conversion | | test.go:79:13:79:43 | type conversion | semmle.label | type conversion | -| test.go:79:20:79:33 | selection of substructs : slice type | semmle.label | selection of substructs : slice type | -| test.go:79:20:79:36 | index expression : SubStruct | semmle.label | index expression : SubStruct | -| test.go:82:22:82:26 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:82:22:82:26 | &... | semmle.label | &... | | test.go:83:13:83:30 | type conversion | semmle.label | type conversion | -| test.go:86:21:86:25 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:86:21:86:25 | &... | semmle.label | &... | | test.go:87:13:87:30 | type conversion | semmle.label | type conversion | | test.go:92:13:92:37 | type conversion | semmle.label | type conversion | -| test.go:92:20:92:36 | call to Value : string | semmle.label | call to Value : string | +| test.go:92:20:92:36 | call to Value | semmle.label | call to Value | | test.go:93:13:93:49 | type conversion | semmle.label | type conversion | -| test.go:93:20:93:39 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type | +| test.go:93:20:93:39 | call to RawValue | semmle.label | call to RawValue | | test.go:94:13:94:38 | type conversion | semmle.label | type conversion | -| test.go:94:20:94:37 | call to String : string | semmle.label | call to String : string | +| test.go:94:20:94:37 | call to String | semmle.label | call to String | | test.go:95:13:95:37 | type conversion | semmle.label | type conversion | -| test.go:95:20:95:36 | call to Value : string | semmle.label | call to Value : string | +| test.go:95:20:95:36 | call to Value | semmle.label | call to Value | | test.go:96:13:96:49 | type conversion | semmle.label | type conversion | -| test.go:96:20:96:39 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type | +| test.go:96:20:96:39 | call to RawValue | semmle.label | call to RawValue | | test.go:97:13:97:38 | type conversion | semmle.label | type conversion | -| test.go:97:20:97:37 | call to String : string | semmle.label | call to String : string | +| test.go:97:20:97:37 | call to String | semmle.label | call to String | | test.go:98:13:98:38 | type conversion | semmle.label | type conversion | -| test.go:98:20:98:37 | call to Value : string | semmle.label | call to Value : string | +| test.go:98:20:98:37 | call to Value | semmle.label | call to Value | | test.go:99:13:99:50 | type conversion | semmle.label | type conversion | -| test.go:99:20:99:40 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type | +| test.go:99:20:99:40 | call to RawValue | semmle.label | call to RawValue | | test.go:100:13:100:39 | type conversion | semmle.label | type conversion | -| test.go:100:20:100:38 | call to String : string | semmle.label | call to String : string | -| test.go:106:9:106:13 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:100:20:100:38 | call to String | semmle.label | call to String | +| test.go:106:9:106:13 | &... | semmle.label | &... | | test.go:107:13:107:33 | type conversion | semmle.label | type conversion | -| test.go:107:20:107:26 | implicit dereference : MyStruct | semmle.label | implicit dereference : MyStruct | -| test.go:107:20:107:26 | index expression : pointer type | semmle.label | index expression : pointer type | -| test.go:110:9:110:12 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:110:9:110:12 | &... | semmle.label | &... | | test.go:111:13:111:29 | type conversion | semmle.label | type conversion | -| test.go:114:12:114:19 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:114:12:114:19 | &... | semmle.label | &... | | test.go:115:13:115:48 | type conversion | semmle.label | type conversion | -| test.go:118:16:118:24 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:118:16:118:24 | &... | semmle.label | &... | | test.go:119:13:119:43 | type conversion | semmle.label | type conversion | -| test.go:122:16:122:23 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:122:16:122:23 | &... | semmle.label | &... | | test.go:123:13:123:39 | type conversion | semmle.label | type conversion | -| test.go:126:15:126:24 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:126:15:126:24 | &... | semmle.label | &... | | test.go:127:13:127:47 | type conversion | semmle.label | type conversion | -| test.go:130:18:130:30 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:130:18:130:30 | &... | semmle.label | &... | | test.go:131:13:131:38 | type conversion | semmle.label | type conversion | -| test.go:137:12:137:19 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:137:12:137:19 | &... | semmle.label | &... | | test.go:138:13:138:48 | type conversion | semmle.label | type conversion | -| test.go:141:16:141:24 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:141:16:141:24 | &... | semmle.label | &... | | test.go:142:13:142:43 | type conversion | semmle.label | type conversion | -| test.go:145:16:145:23 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:145:16:145:23 | &... | semmle.label | &... | | test.go:146:13:146:39 | type conversion | semmle.label | type conversion | -| test.go:149:15:149:24 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:149:15:149:24 | &... | semmle.label | &... | | test.go:150:13:150:47 | type conversion | semmle.label | type conversion | -| test.go:153:18:153:30 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:153:18:153:30 | &... | semmle.label | &... | | test.go:154:13:154:38 | type conversion | semmle.label | type conversion | -| test.go:157:14:157:22 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:157:14:157:22 | &... | semmle.label | &... | | test.go:158:13:158:28 | type conversion | semmle.label | type conversion | -| test.go:161:15:161:24 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:161:15:161:24 | &... | semmle.label | &... | | test.go:162:13:162:32 | type conversion | semmle.label | type conversion | subpaths #select -| test.go:78:13:78:29 | type conversion | test.go:77:13:77:16 | &... : pointer type | test.go:78:13:78:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:77:13:77:16 | &... | stored value | -| test.go:79:13:79:43 | type conversion | test.go:77:13:77:16 | &... : pointer type | test.go:79:13:79:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:77:13:77:16 | &... | stored value | -| test.go:83:13:83:30 | type conversion | test.go:82:22:82:26 | &... : pointer type | test.go:83:13:83:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:82:22:82:26 | &... | stored value | -| test.go:87:13:87:30 | type conversion | test.go:86:21:86:25 | &... : pointer type | test.go:87:13:87:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:86:21:86:25 | &... | stored value | -| test.go:92:13:92:37 | type conversion | test.go:92:20:92:36 | call to Value : string | test.go:92:13:92:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:92:20:92:36 | call to Value | stored value | -| test.go:93:13:93:49 | type conversion | test.go:93:20:93:39 | call to RawValue : basic interface type | test.go:93:13:93:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:93:20:93:39 | call to RawValue | stored value | -| test.go:94:13:94:38 | type conversion | test.go:94:20:94:37 | call to String : string | test.go:94:13:94:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:94:20:94:37 | call to String | stored value | -| test.go:95:13:95:37 | type conversion | test.go:95:20:95:36 | call to Value : string | test.go:95:13:95:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:95:20:95:36 | call to Value | stored value | -| test.go:96:13:96:49 | type conversion | test.go:96:20:96:39 | call to RawValue : basic interface type | test.go:96:13:96:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:96:20:96:39 | call to RawValue | stored value | -| test.go:97:13:97:38 | type conversion | test.go:97:20:97:37 | call to String : string | test.go:97:13:97:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:97:20:97:37 | call to String | stored value | -| test.go:98:13:98:38 | type conversion | test.go:98:20:98:37 | call to Value : string | test.go:98:13:98:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:98:20:98:37 | call to Value | stored value | -| test.go:99:13:99:50 | type conversion | test.go:99:20:99:40 | call to RawValue : basic interface type | test.go:99:13:99:50 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:99:20:99:40 | call to RawValue | stored value | -| test.go:100:13:100:39 | type conversion | test.go:100:20:100:38 | call to String : string | test.go:100:13:100:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:100:20:100:38 | call to String | stored value | -| test.go:107:13:107:33 | type conversion | test.go:106:9:106:13 | &... : pointer type | test.go:107:13:107:33 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:106:9:106:13 | &... | stored value | -| test.go:111:13:111:29 | type conversion | test.go:110:9:110:12 | &... : pointer type | test.go:111:13:111:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:110:9:110:12 | &... | stored value | -| test.go:115:13:115:48 | type conversion | test.go:114:12:114:19 | &... : pointer type | test.go:115:13:115:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:114:12:114:19 | &... | stored value | -| test.go:119:13:119:43 | type conversion | test.go:118:16:118:24 | &... : pointer type | test.go:119:13:119:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:118:16:118:24 | &... | stored value | -| test.go:123:13:123:39 | type conversion | test.go:122:16:122:23 | &... : pointer type | test.go:123:13:123:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:122:16:122:23 | &... | stored value | -| test.go:127:13:127:47 | type conversion | test.go:126:15:126:24 | &... : pointer type | test.go:127:13:127:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:126:15:126:24 | &... | stored value | -| test.go:131:13:131:38 | type conversion | test.go:130:18:130:30 | &... : pointer type | test.go:131:13:131:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:130:18:130:30 | &... | stored value | -| test.go:138:13:138:48 | type conversion | test.go:137:12:137:19 | &... : pointer type | test.go:138:13:138:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:137:12:137:19 | &... | stored value | -| test.go:142:13:142:43 | type conversion | test.go:141:16:141:24 | &... : pointer type | test.go:142:13:142:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:141:16:141:24 | &... | stored value | -| test.go:146:13:146:39 | type conversion | test.go:145:16:145:23 | &... : pointer type | test.go:146:13:146:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:145:16:145:23 | &... | stored value | -| test.go:150:13:150:47 | type conversion | test.go:149:15:149:24 | &... : pointer type | test.go:150:13:150:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:149:15:149:24 | &... | stored value | -| test.go:154:13:154:38 | type conversion | test.go:153:18:153:30 | &... : pointer type | test.go:154:13:154:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:153:18:153:30 | &... | stored value | -| test.go:158:13:158:28 | type conversion | test.go:157:14:157:22 | &... : pointer type | test.go:158:13:158:28 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:157:14:157:22 | &... | stored value | -| test.go:162:13:162:32 | type conversion | test.go:161:15:161:24 | &... : pointer type | test.go:162:13:162:32 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:161:15:161:24 | &... | stored value | +| test.go:78:13:78:29 | type conversion | test.go:77:13:77:16 | &... | test.go:78:13:78:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:77:13:77:16 | &... | stored value | +| test.go:79:13:79:43 | type conversion | test.go:77:13:77:16 | &... | test.go:79:13:79:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:77:13:77:16 | &... | stored value | +| test.go:83:13:83:30 | type conversion | test.go:82:22:82:26 | &... | test.go:83:13:83:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:82:22:82:26 | &... | stored value | +| test.go:87:13:87:30 | type conversion | test.go:86:21:86:25 | &... | test.go:87:13:87:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:86:21:86:25 | &... | stored value | +| test.go:92:13:92:37 | type conversion | test.go:92:20:92:36 | call to Value | test.go:92:13:92:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:92:20:92:36 | call to Value | stored value | +| test.go:93:13:93:49 | type conversion | test.go:93:20:93:39 | call to RawValue | test.go:93:13:93:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:93:20:93:39 | call to RawValue | stored value | +| test.go:94:13:94:38 | type conversion | test.go:94:20:94:37 | call to String | test.go:94:13:94:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:94:20:94:37 | call to String | stored value | +| test.go:95:13:95:37 | type conversion | test.go:95:20:95:36 | call to Value | test.go:95:13:95:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:95:20:95:36 | call to Value | stored value | +| test.go:96:13:96:49 | type conversion | test.go:96:20:96:39 | call to RawValue | test.go:96:13:96:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:96:20:96:39 | call to RawValue | stored value | +| test.go:97:13:97:38 | type conversion | test.go:97:20:97:37 | call to String | test.go:97:13:97:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:97:20:97:37 | call to String | stored value | +| test.go:98:13:98:38 | type conversion | test.go:98:20:98:37 | call to Value | test.go:98:13:98:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:98:20:98:37 | call to Value | stored value | +| test.go:99:13:99:50 | type conversion | test.go:99:20:99:40 | call to RawValue | test.go:99:13:99:50 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:99:20:99:40 | call to RawValue | stored value | +| test.go:100:13:100:39 | type conversion | test.go:100:20:100:38 | call to String | test.go:100:13:100:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:100:20:100:38 | call to String | stored value | +| test.go:107:13:107:33 | type conversion | test.go:106:9:106:13 | &... | test.go:107:13:107:33 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:106:9:106:13 | &... | stored value | +| test.go:111:13:111:29 | type conversion | test.go:110:9:110:12 | &... | test.go:111:13:111:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:110:9:110:12 | &... | stored value | +| test.go:115:13:115:48 | type conversion | test.go:114:12:114:19 | &... | test.go:115:13:115:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:114:12:114:19 | &... | stored value | +| test.go:119:13:119:43 | type conversion | test.go:118:16:118:24 | &... | test.go:119:13:119:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:118:16:118:24 | &... | stored value | +| test.go:123:13:123:39 | type conversion | test.go:122:16:122:23 | &... | test.go:123:13:123:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:122:16:122:23 | &... | stored value | +| test.go:127:13:127:47 | type conversion | test.go:126:15:126:24 | &... | test.go:127:13:127:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:126:15:126:24 | &... | stored value | +| test.go:131:13:131:38 | type conversion | test.go:130:18:130:30 | &... | test.go:131:13:131:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:130:18:130:30 | &... | stored value | +| test.go:138:13:138:48 | type conversion | test.go:137:12:137:19 | &... | test.go:138:13:138:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:137:12:137:19 | &... | stored value | +| test.go:142:13:142:43 | type conversion | test.go:141:16:141:24 | &... | test.go:142:13:142:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:141:16:141:24 | &... | stored value | +| test.go:146:13:146:39 | type conversion | test.go:145:16:145:23 | &... | test.go:146:13:146:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:145:16:145:23 | &... | stored value | +| test.go:150:13:150:47 | type conversion | test.go:149:15:149:24 | &... | test.go:150:13:150:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:149:15:149:24 | &... | stored value | +| test.go:154:13:154:38 | type conversion | test.go:153:18:153:30 | &... | test.go:154:13:154:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:153:18:153:30 | &... | stored value | +| test.go:158:13:158:28 | type conversion | test.go:157:14:157:22 | &... | test.go:158:13:158:28 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:157:14:157:22 | &... | stored value | +| test.go:162:13:162:32 | type conversion | test.go:161:15:161:24 | &... | test.go:162:13:162:32 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:161:15:161:24 | &... | stored value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected index d934df79582..cc6d95f8717 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.expected @@ -1,30 +1,24 @@ edges -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:16 | implicit dereference : URL | -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:16 | selection of URL : pointer type | -| test.go:13:12:13:16 | implicit dereference : URL | test.go:13:12:13:21 | selection of Path : string | -| test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:16 | implicit dereference : URL | -| test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:16 | selection of URL : pointer type | -| test.go:13:12:13:16 | selection of URL : pointer type | test.go:13:12:13:21 | selection of Path : string | -| test.go:13:12:13:21 | selection of Path : string | test.go:21:18:21:23 | hidden : string | -| test.go:21:18:21:23 | hidden : string | test.go:21:11:21:24 | type conversion | -| test.go:22:18:22:45 | call to URLParam : string | test.go:22:11:22:46 | type conversion | -| test.go:23:18:23:60 | call to URLParamFromCtx : string | test.go:23:11:23:61 | type conversion | -| test.go:24:18:24:71 | call to URLParam : string | test.go:24:11:24:72 | type conversion | +| test.go:13:12:13:16 | selection of URL | test.go:13:12:13:21 | selection of Path | +| test.go:13:12:13:21 | selection of Path | test.go:21:18:21:23 | hidden | +| test.go:21:18:21:23 | hidden | test.go:21:11:21:24 | type conversion | +| test.go:22:18:22:45 | call to URLParam | test.go:22:11:22:46 | type conversion | +| test.go:23:18:23:60 | call to URLParamFromCtx | test.go:23:11:23:61 | type conversion | +| test.go:24:18:24:71 | call to URLParam | test.go:24:11:24:72 | type conversion | nodes -| test.go:13:12:13:16 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| test.go:13:12:13:16 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| test.go:13:12:13:21 | selection of Path : string | semmle.label | selection of Path : string | +| test.go:13:12:13:16 | selection of URL | semmle.label | selection of URL | +| test.go:13:12:13:21 | selection of Path | semmle.label | selection of Path | | test.go:21:11:21:24 | type conversion | semmle.label | type conversion | -| test.go:21:18:21:23 | hidden : string | semmle.label | hidden : string | +| test.go:21:18:21:23 | hidden | semmle.label | hidden | | test.go:22:11:22:46 | type conversion | semmle.label | type conversion | -| test.go:22:18:22:45 | call to URLParam : string | semmle.label | call to URLParam : string | +| test.go:22:18:22:45 | call to URLParam | semmle.label | call to URLParam | | test.go:23:11:23:61 | type conversion | semmle.label | type conversion | -| test.go:23:18:23:60 | call to URLParamFromCtx : string | semmle.label | call to URLParamFromCtx : string | +| test.go:23:18:23:60 | call to URLParamFromCtx | semmle.label | call to URLParamFromCtx | | test.go:24:11:24:72 | type conversion | semmle.label | type conversion | -| test.go:24:18:24:71 | call to URLParam : string | semmle.label | call to URLParam : string | +| test.go:24:18:24:71 | call to URLParam | semmle.label | call to URLParam | subpaths #select -| test.go:21:11:21:24 | type conversion | test.go:13:12:13:16 | selection of URL : pointer type | test.go:21:11:21:24 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:13:12:13:16 | selection of URL | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:22:11:22:46 | type conversion | test.go:22:18:22:45 | call to URLParam : string | test.go:22:11:22:46 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:18:22:45 | call to URLParam | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:23:11:23:61 | type conversion | test.go:23:18:23:60 | call to URLParamFromCtx : string | test.go:23:11:23:61 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:23:18:23:60 | call to URLParamFromCtx | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:24:11:24:72 | type conversion | test.go:24:18:24:71 | call to URLParam : string | test.go:24:11:24:72 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:24:18:24:71 | call to URLParam | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:21:11:21:24 | type conversion | test.go:13:12:13:16 | selection of URL | test.go:21:11:21:24 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:13:12:13:16 | selection of URL | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:22:11:22:46 | type conversion | test.go:22:18:22:45 | call to URLParam | test.go:22:11:22:46 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:18:22:45 | call to URLParam | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:23:11:23:61 | type conversion | test.go:23:18:23:60 | call to URLParamFromCtx | test.go:23:11:23:61 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:23:18:23:60 | call to URLParamFromCtx | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:24:11:24:72 | type conversion | test.go:24:18:24:71 | call to URLParam | test.go:24:11:24:72 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:24:18:24:71 | call to URLParam | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index e29c066c9b5..10ad0046423 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -1,20 +1,18 @@ edges -| test.go:170:11:170:32 | call to Param : string | test.go:171:20:171:24 | param | -| test.go:176:11:176:32 | call to Param : string | test.go:180:20:180:28 | ...+... | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String | -| test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String | +| test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | +| test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | +| test.go:188:10:188:26 | selection of URL | test.go:191:21:191:32 | call to String | +| test.go:188:10:188:26 | selection of URL | test.go:191:21:191:32 | call to String | nodes -| test.go:170:11:170:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:170:11:170:32 | call to Param | semmle.label | call to Param | | test.go:171:20:171:24 | param | semmle.label | param | -| test.go:176:11:176:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:176:11:176:32 | call to Param | semmle.label | call to Param | | test.go:180:20:180:28 | ...+... | semmle.label | ...+... | -| test.go:188:10:188:26 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| test.go:188:10:188:26 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| test.go:188:10:188:26 | selection of URL | semmle.label | selection of URL | +| test.go:188:10:188:26 | selection of URL | semmle.label | selection of URL | | test.go:191:21:191:32 | call to String | semmle.label | call to String | | test.go:191:21:191:32 | call to String | semmle.label | call to String | subpaths #select -| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param : string | test.go:171:20:171:24 | param | Untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value | -| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param : string | test.go:180:20:180:28 | ...+... | Untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value | +| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | Untrusted URL redirection depends on a $@. | test.go:170:11:170:32 | call to Param | user-provided value | +| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | Untrusted URL redirection depends on a $@. | test.go:176:11:176:32 | call to Param | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected index f6d15897938..641ceddb08f 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected @@ -1,120 +1,80 @@ edges -| test.go:13:11:13:32 | call to Param : string | test.go:14:16:14:20 | param | -| test.go:19:11:19:27 | call to ParamValues : slice type | test.go:20:16:20:20 | param | -| test.go:25:11:25:37 | call to QueryParam : string | test.go:26:16:26:20 | param | -| test.go:31:11:31:27 | call to QueryParams : Values | test.go:32:16:32:20 | param | -| test.go:37:10:37:26 | call to QueryString : string | test.go:38:16:38:19 | qstr | -| test.go:43:9:43:34 | call to FormValue : string | test.go:44:16:44:18 | val | -| test.go:49:2:49:30 | ... := ...[0] : Values | test.go:50:16:50:37 | index expression | -| test.go:55:2:55:46 | ... := ...[0] : pointer type | test.go:59:20:59:25 | buffer | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:19 | implicit dereference : Form | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:25 | selection of Value : map type | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:38 | index expression : slice type | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:19 | implicit dereference : Form | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:25 | selection of Value : map type | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:38 | index expression : slice type | -| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:25 | selection of Value : map type | test.go:65:16:65:38 | index expression : slice type | -| test.go:65:16:65:25 | selection of Value : map type | test.go:65:16:65:41 | index expression | -| test.go:65:16:65:38 | index expression : slice type | test.go:65:16:65:41 | index expression | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:19 | implicit dereference : Form | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:24 | selection of File : map type | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:40 | index expression : slice type | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:19 | implicit dereference : Form | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:24 | selection of File : map type | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:40 | index expression : slice type | -| test.go:71:16:71:19 | implicit dereference : Form | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:24 | selection of File : map type | test.go:71:16:71:40 | index expression : slice type | -| test.go:71:16:71:24 | selection of File : map type | test.go:75:20:75:25 | buffer | -| test.go:71:16:71:40 | index expression : slice type | test.go:75:20:75:25 | buffer | -| test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:18 | implicit dereference : Cookie | -| test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:24 | selection of Value | -| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:18 | implicit dereference : Cookie | -| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:24 | selection of Value | -| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:25 | index expression : pointer type | -| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:31 | selection of Value | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:25 | index expression : pointer type | -| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:31 | selection of Value | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:25 | implicit dereference : Cookie | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:25 | index expression : pointer type | -| test.go:87:16:87:25 | index expression : pointer type | test.go:87:16:87:31 | selection of Value | -| test.go:97:11:97:15 | &... : pointer type | test.go:98:16:98:21 | selection of s | -| test.go:111:21:111:42 | call to Param : string | test.go:112:16:112:42 | type assertion | -| test.go:122:11:122:32 | call to Param : string | test.go:123:16:123:20 | param | -| test.go:128:11:128:32 | call to Param : string | test.go:129:20:129:32 | type conversion | -| test.go:134:11:134:32 | call to Param : string | test.go:135:29:135:41 | type conversion | -| test.go:146:11:146:32 | call to Param : string | test.go:148:31:148:36 | reader | -| test.go:162:11:162:32 | call to Param : string | test.go:163:23:163:35 | type conversion | +| test.go:13:11:13:32 | call to Param | test.go:14:16:14:20 | param | +| test.go:19:11:19:27 | call to ParamValues | test.go:20:16:20:20 | param | +| test.go:25:11:25:37 | call to QueryParam | test.go:26:16:26:20 | param | +| test.go:31:11:31:27 | call to QueryParams | test.go:32:16:32:20 | param | +| test.go:37:10:37:26 | call to QueryString | test.go:38:16:38:19 | qstr | +| test.go:43:9:43:34 | call to FormValue | test.go:44:16:44:18 | val | +| test.go:49:2:49:30 | ... := ...[0] | test.go:50:16:50:37 | index expression | +| test.go:55:2:55:46 | ... := ...[0] | test.go:59:20:59:25 | buffer | +| test.go:64:2:64:31 | ... := ...[0] | test.go:65:16:65:41 | index expression | +| test.go:70:2:70:31 | ... := ...[0] | test.go:75:20:75:25 | buffer | +| test.go:80:2:80:32 | ... := ...[0] | test.go:81:16:81:24 | selection of Value | +| test.go:86:13:86:25 | call to Cookies | test.go:87:16:87:31 | selection of Value | +| test.go:97:11:97:15 | &... | test.go:98:16:98:21 | selection of s | +| test.go:111:21:111:42 | call to Param | test.go:112:16:112:42 | type assertion | +| test.go:122:11:122:32 | call to Param | test.go:123:16:123:20 | param | +| test.go:128:11:128:32 | call to Param | test.go:129:20:129:32 | type conversion | +| test.go:134:11:134:32 | call to Param | test.go:135:29:135:41 | type conversion | +| test.go:146:11:146:32 | call to Param | test.go:148:31:148:36 | reader | +| test.go:162:11:162:32 | call to Param | test.go:163:23:163:35 | type conversion | nodes -| test.go:13:11:13:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:13:11:13:32 | call to Param | semmle.label | call to Param | | test.go:14:16:14:20 | param | semmle.label | param | -| test.go:19:11:19:27 | call to ParamValues : slice type | semmle.label | call to ParamValues : slice type | +| test.go:19:11:19:27 | call to ParamValues | semmle.label | call to ParamValues | | test.go:20:16:20:20 | param | semmle.label | param | -| test.go:25:11:25:37 | call to QueryParam : string | semmle.label | call to QueryParam : string | +| test.go:25:11:25:37 | call to QueryParam | semmle.label | call to QueryParam | | test.go:26:16:26:20 | param | semmle.label | param | -| test.go:31:11:31:27 | call to QueryParams : Values | semmle.label | call to QueryParams : Values | +| test.go:31:11:31:27 | call to QueryParams | semmle.label | call to QueryParams | | test.go:32:16:32:20 | param | semmle.label | param | -| test.go:37:10:37:26 | call to QueryString : string | semmle.label | call to QueryString : string | +| test.go:37:10:37:26 | call to QueryString | semmle.label | call to QueryString | | test.go:38:16:38:19 | qstr | semmle.label | qstr | -| test.go:43:9:43:34 | call to FormValue : string | semmle.label | call to FormValue : string | +| test.go:43:9:43:34 | call to FormValue | semmle.label | call to FormValue | | test.go:44:16:44:18 | val | semmle.label | val | -| test.go:49:2:49:30 | ... := ...[0] : Values | semmle.label | ... := ...[0] : Values | +| test.go:49:2:49:30 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:50:16:50:37 | index expression | semmle.label | index expression | -| test.go:55:2:55:46 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| test.go:55:2:55:46 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:59:20:59:25 | buffer | semmle.label | buffer | -| test.go:64:2:64:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:65:16:65:19 | implicit dereference : Form | semmle.label | implicit dereference : Form | -| test.go:65:16:65:25 | selection of Value : map type | semmle.label | selection of Value : map type | -| test.go:65:16:65:38 | index expression : slice type | semmle.label | index expression : slice type | +| test.go:64:2:64:31 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:65:16:65:41 | index expression | semmle.label | index expression | -| test.go:70:2:70:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:71:16:71:19 | implicit dereference : Form | semmle.label | implicit dereference : Form | -| test.go:71:16:71:24 | selection of File : map type | semmle.label | selection of File : map type | -| test.go:71:16:71:40 | index expression : slice type | semmle.label | index expression : slice type | +| test.go:70:2:70:31 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:75:20:75:25 | buffer | semmle.label | buffer | -| test.go:80:2:80:32 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| test.go:81:16:81:18 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | +| test.go:80:2:80:32 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:81:16:81:24 | selection of Value | semmle.label | selection of Value | -| test.go:86:13:86:25 | call to Cookies : slice type | semmle.label | call to Cookies : slice type | -| test.go:87:16:87:25 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | -| test.go:87:16:87:25 | index expression : pointer type | semmle.label | index expression : pointer type | +| test.go:86:13:86:25 | call to Cookies | semmle.label | call to Cookies | | test.go:87:16:87:31 | selection of Value | semmle.label | selection of Value | -| test.go:97:11:97:15 | &... : pointer type | semmle.label | &... : pointer type | +| test.go:97:11:97:15 | &... | semmle.label | &... | | test.go:98:16:98:21 | selection of s | semmle.label | selection of s | -| test.go:111:21:111:42 | call to Param : string | semmle.label | call to Param : string | +| test.go:111:21:111:42 | call to Param | semmle.label | call to Param | | test.go:112:16:112:42 | type assertion | semmle.label | type assertion | -| test.go:122:11:122:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:122:11:122:32 | call to Param | semmle.label | call to Param | | test.go:123:16:123:20 | param | semmle.label | param | -| test.go:128:11:128:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:128:11:128:32 | call to Param | semmle.label | call to Param | | test.go:129:20:129:32 | type conversion | semmle.label | type conversion | -| test.go:134:11:134:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:134:11:134:32 | call to Param | semmle.label | call to Param | | test.go:135:29:135:41 | type conversion | semmle.label | type conversion | -| test.go:146:11:146:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:146:11:146:32 | call to Param | semmle.label | call to Param | | test.go:148:31:148:36 | reader | semmle.label | reader | -| test.go:162:11:162:32 | call to Param : string | semmle.label | call to Param : string | +| test.go:162:11:162:32 | call to Param | semmle.label | call to Param | | test.go:163:23:163:35 | type conversion | semmle.label | type conversion | subpaths #select -| test.go:14:16:14:20 | param | test.go:13:11:13:32 | call to Param : string | test.go:14:16:14:20 | param | Cross-site scripting vulnerability due to $@. | test.go:13:11:13:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:20:16:20:20 | param | test.go:19:11:19:27 | call to ParamValues : slice type | test.go:20:16:20:20 | param | Cross-site scripting vulnerability due to $@. | test.go:19:11:19:27 | call to ParamValues | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:26:16:26:20 | param | test.go:25:11:25:37 | call to QueryParam : string | test.go:26:16:26:20 | param | Cross-site scripting vulnerability due to $@. | test.go:25:11:25:37 | call to QueryParam | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:32:16:32:20 | param | test.go:31:11:31:27 | call to QueryParams : Values | test.go:32:16:32:20 | param | Cross-site scripting vulnerability due to $@. | test.go:31:11:31:27 | call to QueryParams | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:38:16:38:19 | qstr | test.go:37:10:37:26 | call to QueryString : string | test.go:38:16:38:19 | qstr | Cross-site scripting vulnerability due to $@. | test.go:37:10:37:26 | call to QueryString | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:44:16:44:18 | val | test.go:43:9:43:34 | call to FormValue : string | test.go:44:16:44:18 | val | Cross-site scripting vulnerability due to $@. | test.go:43:9:43:34 | call to FormValue | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:50:16:50:37 | index expression | test.go:49:2:49:30 | ... := ...[0] : Values | test.go:50:16:50:37 | index expression | Cross-site scripting vulnerability due to $@. | test.go:49:2:49:30 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:59:20:59:25 | buffer | test.go:55:2:55:46 | ... := ...[0] : pointer type | test.go:59:20:59:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:55:2:55:46 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:65:16:65:41 | index expression | test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:41 | index expression | Cross-site scripting vulnerability due to $@. | test.go:64:2:64:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:75:20:75:25 | buffer | test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:75:20:75:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:70:2:70:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:81:16:81:24 | selection of Value | test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:80:2:80:32 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:87:16:87:31 | selection of Value | test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:86:13:86:25 | call to Cookies | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:98:16:98:21 | selection of s | test.go:97:11:97:15 | &... : pointer type | test.go:98:16:98:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:97:11:97:15 | &... | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:112:16:112:42 | type assertion | test.go:111:21:111:42 | call to Param : string | test.go:112:16:112:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:111:21:111:42 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:123:16:123:20 | param | test.go:122:11:122:32 | call to Param : string | test.go:123:16:123:20 | param | Cross-site scripting vulnerability due to $@. | test.go:122:11:122:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:129:20:129:32 | type conversion | test.go:128:11:128:32 | call to Param : string | test.go:129:20:129:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:128:11:128:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:135:29:135:41 | type conversion | test.go:134:11:134:32 | call to Param : string | test.go:135:29:135:41 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:134:11:134:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:148:31:148:36 | reader | test.go:146:11:146:32 | call to Param : string | test.go:148:31:148:36 | reader | Cross-site scripting vulnerability due to $@. | test.go:146:11:146:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:163:23:163:35 | type conversion | test.go:162:11:162:32 | call to Param : string | test.go:163:23:163:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:162:11:162:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:14:16:14:20 | param | test.go:13:11:13:32 | call to Param | test.go:14:16:14:20 | param | Cross-site scripting vulnerability due to $@. | test.go:13:11:13:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:20:16:20:20 | param | test.go:19:11:19:27 | call to ParamValues | test.go:20:16:20:20 | param | Cross-site scripting vulnerability due to $@. | test.go:19:11:19:27 | call to ParamValues | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:26:16:26:20 | param | test.go:25:11:25:37 | call to QueryParam | test.go:26:16:26:20 | param | Cross-site scripting vulnerability due to $@. | test.go:25:11:25:37 | call to QueryParam | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:32:16:32:20 | param | test.go:31:11:31:27 | call to QueryParams | test.go:32:16:32:20 | param | Cross-site scripting vulnerability due to $@. | test.go:31:11:31:27 | call to QueryParams | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:38:16:38:19 | qstr | test.go:37:10:37:26 | call to QueryString | test.go:38:16:38:19 | qstr | Cross-site scripting vulnerability due to $@. | test.go:37:10:37:26 | call to QueryString | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:44:16:44:18 | val | test.go:43:9:43:34 | call to FormValue | test.go:44:16:44:18 | val | Cross-site scripting vulnerability due to $@. | test.go:43:9:43:34 | call to FormValue | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:50:16:50:37 | index expression | test.go:49:2:49:30 | ... := ...[0] | test.go:50:16:50:37 | index expression | Cross-site scripting vulnerability due to $@. | test.go:49:2:49:30 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:59:20:59:25 | buffer | test.go:55:2:55:46 | ... := ...[0] | test.go:59:20:59:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:55:2:55:46 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:65:16:65:41 | index expression | test.go:64:2:64:31 | ... := ...[0] | test.go:65:16:65:41 | index expression | Cross-site scripting vulnerability due to $@. | test.go:64:2:64:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:75:20:75:25 | buffer | test.go:70:2:70:31 | ... := ...[0] | test.go:75:20:75:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:70:2:70:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:81:16:81:24 | selection of Value | test.go:80:2:80:32 | ... := ...[0] | test.go:81:16:81:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:80:2:80:32 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:87:16:87:31 | selection of Value | test.go:86:13:86:25 | call to Cookies | test.go:87:16:87:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:86:13:86:25 | call to Cookies | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:98:16:98:21 | selection of s | test.go:97:11:97:15 | &... | test.go:98:16:98:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:97:11:97:15 | &... | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:112:16:112:42 | type assertion | test.go:111:21:111:42 | call to Param | test.go:112:16:112:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:111:21:111:42 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:123:16:123:20 | param | test.go:122:11:122:32 | call to Param | test.go:123:16:123:20 | param | Cross-site scripting vulnerability due to $@. | test.go:122:11:122:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:129:20:129:32 | type conversion | test.go:128:11:128:32 | call to Param | test.go:129:20:129:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:128:11:128:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:135:29:135:41 | type conversion | test.go:134:11:134:32 | call to Param | test.go:135:29:135:41 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:134:11:134:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:148:31:148:36 | reader | test.go:146:11:146:32 | call to Param | test.go:148:31:148:36 | reader | Cross-site scripting vulnerability due to $@. | test.go:146:11:146:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:163:23:163:35 | type conversion | test.go:162:11:162:32 | call to Param | test.go:163:23:163:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:162:11:162:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected index af6b671225b..54d739e8a90 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected @@ -1,4 +1,4 @@ -| jsoniter.go:28:15:28:24 | selection of field | jsoniter.go:23:20:23:38 | call to getUntrustedBytes : slice type | jsoniter.go:28:15:28:24 | selection of field | This command depends on $@. | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | a user-provided value | -| jsoniter.go:32:15:32:25 | selection of field | jsoniter.go:23:20:23:38 | call to getUntrustedBytes : slice type | jsoniter.go:32:15:32:25 | selection of field | This command depends on $@. | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | a user-provided value | -| jsoniter.go:36:15:36:25 | selection of field | jsoniter.go:24:21:24:40 | call to getUntrustedString : string | jsoniter.go:36:15:36:25 | selection of field | This command depends on $@. | jsoniter.go:24:21:24:40 | call to getUntrustedString | a user-provided value | -| jsoniter.go:40:15:40:25 | selection of field | jsoniter.go:24:21:24:40 | call to getUntrustedString : string | jsoniter.go:40:15:40:25 | selection of field | This command depends on $@. | jsoniter.go:24:21:24:40 | call to getUntrustedString | a user-provided value | +| jsoniter.go:28:15:28:24 | selection of field | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | jsoniter.go:28:15:28:24 | selection of field | This command depends on $@. | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | a user-provided value | +| jsoniter.go:32:15:32:25 | selection of field | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | jsoniter.go:32:15:32:25 | selection of field | This command depends on $@. | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | a user-provided value | +| jsoniter.go:36:15:36:25 | selection of field | jsoniter.go:24:21:24:40 | call to getUntrustedString | jsoniter.go:36:15:36:25 | selection of field | This command depends on $@. | jsoniter.go:24:21:24:40 | call to getUntrustedString | a user-provided value | +| jsoniter.go:40:15:40:25 | selection of field | jsoniter.go:24:21:24:40 | call to getUntrustedString | jsoniter.go:40:15:40:25 | selection of field | This command depends on $@. | jsoniter.go:24:21:24:40 | call to getUntrustedString | a user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected b/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected index 4c252dadb93..e60cc051e17 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected @@ -1,14 +1,14 @@ -| gorestful.go:15:15:15:47 | index expression | gorestful.go:15:15:15:44 | call to QueryParameters : slice type | gorestful.go:15:15:15:47 | index expression | This command depends on $@. | gorestful.go:15:15:15:44 | call to QueryParameters | a user-provided value | +| gorestful.go:15:15:15:47 | index expression | gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | This command depends on $@. | gorestful.go:15:15:15:44 | call to QueryParameters | a user-provided value | | gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful.go:16:15:16:43 | call to QueryParameter | a user-provided value | -| gorestful.go:18:15:18:17 | val | gorestful.go:17:12:17:39 | call to BodyParameter : tuple type | gorestful.go:18:15:18:17 | val | This command depends on $@. | gorestful.go:17:12:17:39 | call to BodyParameter | a user-provided value | +| gorestful.go:18:15:18:17 | val | gorestful.go:17:12:17:39 | call to BodyParameter | gorestful.go:18:15:18:17 | val | This command depends on $@. | gorestful.go:17:12:17:39 | call to BodyParameter | a user-provided value | | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful.go:19:15:19:44 | call to HeaderParameter | a user-provided value | | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful.go:20:15:20:42 | call to PathParameter | a user-provided value | -| gorestful.go:21:15:21:45 | index expression | gorestful.go:21:15:21:38 | call to PathParameters : map type | gorestful.go:21:15:21:45 | index expression | This command depends on $@. | gorestful.go:21:15:21:38 | call to PathParameters | a user-provided value | -| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... : pointer type | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... | a user-provided value | -| gorestful_v2.go:15:15:15:47 | index expression | gorestful_v2.go:15:15:15:44 | call to QueryParameters : slice type | gorestful_v2.go:15:15:15:47 | index expression | This command depends on $@. | gorestful_v2.go:15:15:15:44 | call to QueryParameters | a user-provided value | +| gorestful.go:21:15:21:45 | index expression | gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | This command depends on $@. | gorestful.go:21:15:21:38 | call to PathParameters | a user-provided value | +| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... | a user-provided value | +| gorestful_v2.go:15:15:15:47 | index expression | gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | This command depends on $@. | gorestful_v2.go:15:15:15:44 | call to QueryParameters | a user-provided value | | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful_v2.go:16:15:16:43 | call to QueryParameter | a user-provided value | -| gorestful_v2.go:18:15:18:17 | val | gorestful_v2.go:17:12:17:39 | call to BodyParameter : tuple type | gorestful_v2.go:18:15:18:17 | val | This command depends on $@. | gorestful_v2.go:17:12:17:39 | call to BodyParameter | a user-provided value | +| gorestful_v2.go:18:15:18:17 | val | gorestful_v2.go:17:12:17:39 | call to BodyParameter | gorestful_v2.go:18:15:18:17 | val | This command depends on $@. | gorestful_v2.go:17:12:17:39 | call to BodyParameter | a user-provided value | | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | a user-provided value | | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful_v2.go:20:15:20:42 | call to PathParameter | a user-provided value | -| gorestful_v2.go:21:15:21:45 | index expression | gorestful_v2.go:21:15:21:38 | call to PathParameters : map type | gorestful_v2.go:21:15:21:45 | index expression | This command depends on $@. | gorestful_v2.go:21:15:21:38 | call to PathParameters | a user-provided value | -| gorestful_v2.go:24:15:24:21 | selection of cmd | gorestful_v2.go:23:21:23:24 | &... : pointer type | gorestful_v2.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful_v2.go:23:21:23:24 | &... | a user-provided value | +| gorestful_v2.go:21:15:21:45 | index expression | gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | This command depends on $@. | gorestful_v2.go:21:15:21:38 | call to PathParameters | a user-provided value | +| gorestful_v2.go:24:15:24:21 | selection of cmd | gorestful_v2.go:23:21:23:24 | &... | gorestful_v2.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful_v2.go:23:21:23:24 | &... | a user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Protobuf/TaintFlows.expected b/go/ql/test/library-tests/semmle/go/frameworks/Protobuf/TaintFlows.expected index b8d9451ba37..4c70d92720b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Protobuf/TaintFlows.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Protobuf/TaintFlows.expected @@ -1,33 +1,33 @@ -| testDeprecatedApi.go:22:22:22:41 | call to getUntrustedString : string | testDeprecatedApi.go:26:12:26:21 | serialized | -| testDeprecatedApi.go:31:22:31:41 | call to getUntrustedString : string | testDeprecatedApi.go:37:12:37:21 | serialized | -| testDeprecatedApi.go:41:25:41:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:45:13:45:29 | selection of Description | -| testDeprecatedApi.go:49:25:49:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:53:13:53:34 | call to GetDescription | -| testDeprecatedApi.go:58:23:58:42 | call to getUntrustedString : string | testDeprecatedApi.go:65:12:65:21 | serialized | -| testDeprecatedApi.go:70:14:70:33 | call to getUntrustedString : string | testDeprecatedApi.go:77:12:77:21 | serialized | -| testDeprecatedApi.go:85:24:85:43 | call to getUntrustedString : string | testDeprecatedApi.go:89:12:89:21 | serialized | -| testDeprecatedApi.go:93:25:93:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:97:13:97:31 | selection of Msg | -| testDeprecatedApi.go:104:22:104:41 | call to getUntrustedString : string | testDeprecatedApi.go:105:13:105:20 | selection of Id | -| testDeprecatedApi.go:112:22:112:41 | call to getUntrustedString : string | testDeprecatedApi.go:117:12:117:21 | serialized | -| testDeprecatedApi.go:133:29:133:48 | call to getUntrustedString : string | testDeprecatedApi.go:137:12:137:21 | serialized | -| testDeprecatedApi.go:143:20:143:39 | call to getUntrustedString : string | testDeprecatedApi.go:148:12:148:21 | serialized | -| testDeprecatedApi.go:152:25:152:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:157:13:157:36 | index expression | -| testDeprecatedApi.go:161:25:161:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:168:13:168:25 | index expression | -| testDeprecatedApi.go:176:24:176:43 | call to getUntrustedString : string | testDeprecatedApi.go:180:12:180:21 | serialized | -| testModernApi.go:11:22:11:41 | call to getUntrustedString : string | testModernApi.go:15:12:15:21 | serialized | -| testModernApi.go:20:22:20:41 | call to getUntrustedString : string | testModernApi.go:26:12:26:21 | serialized | -| testModernApi.go:30:25:30:43 | call to getUntrustedBytes : slice type | testModernApi.go:34:13:34:29 | selection of Description | -| testModernApi.go:38:25:38:43 | call to getUntrustedBytes : slice type | testModernApi.go:42:13:42:34 | call to GetDescription | -| testModernApi.go:47:23:47:42 | call to getUntrustedString : string | testModernApi.go:54:12:54:21 | serialized | -| testModernApi.go:59:22:59:41 | call to getUntrustedString : string | testModernApi.go:64:12:64:21 | serialized | -| testModernApi.go:71:22:71:41 | call to getUntrustedString : string | testModernApi.go:77:12:77:21 | serialized | -| testModernApi.go:98:14:98:33 | call to getUntrustedString : string | testModernApi.go:105:12:105:21 | serialized | -| testModernApi.go:113:24:113:43 | call to getUntrustedString : string | testModernApi.go:117:12:117:21 | serialized | -| testModernApi.go:121:25:121:43 | call to getUntrustedBytes : slice type | testModernApi.go:125:13:125:31 | selection of Msg | -| testModernApi.go:131:25:131:43 | call to getUntrustedBytes : slice type | testModernApi.go:135:13:135:29 | selection of Description | -| testModernApi.go:142:22:142:41 | call to getUntrustedString : string | testModernApi.go:143:13:143:20 | selection of Id | -| testModernApi.go:150:22:150:41 | call to getUntrustedString : string | testModernApi.go:155:12:155:21 | serialized | -| testModernApi.go:190:29:190:48 | call to getUntrustedString : string | testModernApi.go:194:12:194:21 | serialized | -| testModernApi.go:200:20:200:39 | call to getUntrustedString : string | testModernApi.go:205:12:205:21 | serialized | -| testModernApi.go:209:25:209:43 | call to getUntrustedBytes : slice type | testModernApi.go:214:13:214:36 | index expression | -| testModernApi.go:218:25:218:43 | call to getUntrustedBytes : slice type | testModernApi.go:225:13:225:25 | index expression | -| testModernApi.go:233:24:233:43 | call to getUntrustedString : string | testModernApi.go:237:12:237:21 | serialized | +| testDeprecatedApi.go:22:22:22:41 | call to getUntrustedString | testDeprecatedApi.go:26:12:26:21 | serialized | +| testDeprecatedApi.go:31:22:31:41 | call to getUntrustedString | testDeprecatedApi.go:37:12:37:21 | serialized | +| testDeprecatedApi.go:41:25:41:43 | call to getUntrustedBytes | testDeprecatedApi.go:45:13:45:29 | selection of Description | +| testDeprecatedApi.go:49:25:49:43 | call to getUntrustedBytes | testDeprecatedApi.go:53:13:53:34 | call to GetDescription | +| testDeprecatedApi.go:58:23:58:42 | call to getUntrustedString | testDeprecatedApi.go:65:12:65:21 | serialized | +| testDeprecatedApi.go:70:14:70:33 | call to getUntrustedString | testDeprecatedApi.go:77:12:77:21 | serialized | +| testDeprecatedApi.go:85:24:85:43 | call to getUntrustedString | testDeprecatedApi.go:89:12:89:21 | serialized | +| testDeprecatedApi.go:93:25:93:43 | call to getUntrustedBytes | testDeprecatedApi.go:97:13:97:31 | selection of Msg | +| testDeprecatedApi.go:104:22:104:41 | call to getUntrustedString | testDeprecatedApi.go:105:13:105:20 | selection of Id | +| testDeprecatedApi.go:112:22:112:41 | call to getUntrustedString | testDeprecatedApi.go:117:12:117:21 | serialized | +| testDeprecatedApi.go:133:29:133:48 | call to getUntrustedString | testDeprecatedApi.go:137:12:137:21 | serialized | +| testDeprecatedApi.go:143:20:143:39 | call to getUntrustedString | testDeprecatedApi.go:148:12:148:21 | serialized | +| testDeprecatedApi.go:152:25:152:43 | call to getUntrustedBytes | testDeprecatedApi.go:157:13:157:36 | index expression | +| testDeprecatedApi.go:161:25:161:43 | call to getUntrustedBytes | testDeprecatedApi.go:168:13:168:25 | index expression | +| testDeprecatedApi.go:176:24:176:43 | call to getUntrustedString | testDeprecatedApi.go:180:12:180:21 | serialized | +| testModernApi.go:11:22:11:41 | call to getUntrustedString | testModernApi.go:15:12:15:21 | serialized | +| testModernApi.go:20:22:20:41 | call to getUntrustedString | testModernApi.go:26:12:26:21 | serialized | +| testModernApi.go:30:25:30:43 | call to getUntrustedBytes | testModernApi.go:34:13:34:29 | selection of Description | +| testModernApi.go:38:25:38:43 | call to getUntrustedBytes | testModernApi.go:42:13:42:34 | call to GetDescription | +| testModernApi.go:47:23:47:42 | call to getUntrustedString | testModernApi.go:54:12:54:21 | serialized | +| testModernApi.go:59:22:59:41 | call to getUntrustedString | testModernApi.go:64:12:64:21 | serialized | +| testModernApi.go:71:22:71:41 | call to getUntrustedString | testModernApi.go:77:12:77:21 | serialized | +| testModernApi.go:98:14:98:33 | call to getUntrustedString | testModernApi.go:105:12:105:21 | serialized | +| testModernApi.go:113:24:113:43 | call to getUntrustedString | testModernApi.go:117:12:117:21 | serialized | +| testModernApi.go:121:25:121:43 | call to getUntrustedBytes | testModernApi.go:125:13:125:31 | selection of Msg | +| testModernApi.go:131:25:131:43 | call to getUntrustedBytes | testModernApi.go:135:13:135:29 | selection of Description | +| testModernApi.go:142:22:142:41 | call to getUntrustedString | testModernApi.go:143:13:143:20 | selection of Id | +| testModernApi.go:150:22:150:41 | call to getUntrustedString | testModernApi.go:155:12:155:21 | serialized | +| testModernApi.go:190:29:190:48 | call to getUntrustedString | testModernApi.go:194:12:194:21 | serialized | +| testModernApi.go:200:20:200:39 | call to getUntrustedString | testModernApi.go:205:12:205:21 | serialized | +| testModernApi.go:209:25:209:43 | call to getUntrustedBytes | testModernApi.go:214:13:214:36 | index expression | +| testModernApi.go:218:25:218:43 | call to getUntrustedBytes | testModernApi.go:225:13:225:25 | index expression | +| testModernApi.go:233:24:233:43 | call to getUntrustedString | testModernApi.go:237:12:237:21 | serialized | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index a1e94fbd058..77436c0d149 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -1,14 +1,8 @@ edges -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:27 | implicit dereference : Params | -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | EndToEnd.go:94:20:94:49 | call to Get | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:27 | implicit dereference : Params | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:49 | call to Get | +| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | nodes -| EndToEnd.go:94:20:94:27 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| EndToEnd.go:94:20:94:27 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | subpaths #select -| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params : pointer type | EndToEnd.go:94:20:94:49 | call to Get | Untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | +| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | Untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected index 7f1596dbbf8..7a11d9bd08e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected @@ -1,54 +1,24 @@ edges -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:36:18:36:25 | implicit dereference : Params | -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | EndToEnd.go:37:24:37:26 | buf | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:36:18:36:25 | implicit dereference : Params | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:37:24:37:26 | buf | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:29 | implicit dereference : Params | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | EndToEnd.go:69:22:69:51 | call to Get | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:29 | implicit dereference : Params | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:51 | call to Get | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:29 | implicit dereference : Params | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:29 | selection of Params : pointer type | -| Revel.go:70:22:70:29 | implicit dereference : Params | Revel.go:70:22:70:35 | selection of Query | -| Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:29 | implicit dereference : Params | -| Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:29 | selection of Params : pointer type | -| Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:35 | selection of Query | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:53 | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:58 | selection of Path | +| EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:37:24:37:26 | buf | +| EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:51 | call to Get | +| Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | +| examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | +| examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | nodes -| EndToEnd.go:36:18:36:25 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| EndToEnd.go:36:18:36:25 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| EndToEnd.go:36:18:36:25 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:37:24:37:26 | buf | semmle.label | buf | -| EndToEnd.go:69:22:69:29 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| EndToEnd.go:69:22:69:29 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| EndToEnd.go:69:22:69:29 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:69:22:69:51 | call to Get | semmle.label | call to Get | -| Revel.go:70:22:70:29 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| Revel.go:70:22:70:29 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| Revel.go:70:22:70:29 | selection of Params | semmle.label | selection of Params | | Revel.go:70:22:70:35 | selection of Query | semmle.label | selection of Query | -| examples/booking/app/init.go:36:44:36:48 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| examples/booking/app/init.go:36:44:36:48 | selection of URL | semmle.label | selection of URL | | examples/booking/app/init.go:36:44:36:53 | selection of Path | semmle.label | selection of Path | -| examples/booking/app/init.go:40:49:40:53 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| examples/booking/app/init.go:40:49:40:53 | selection of URL | semmle.label | selection of URL | | examples/booking/app/init.go:40:49:40:58 | selection of Path | semmle.label | selection of Path | subpaths #select -| EndToEnd.go:37:24:37:26 | buf | EndToEnd.go:36:18:36:25 | selection of Params : pointer type | EndToEnd.go:37:24:37:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:36:18:36:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | -| EndToEnd.go:69:22:69:51 | call to Get | EndToEnd.go:69:22:69:29 | selection of Params : pointer type | EndToEnd.go:69:22:69:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:69:22:69:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | -| Revel.go:70:22:70:35 | selection of Query | Revel.go:70:22:70:29 | selection of Params : pointer type | Revel.go:70:22:70:35 | selection of Query | Cross-site scripting vulnerability due to $@. The value is $@. | Revel.go:70:22:70:29 | selection of Params | user-provided value | views/myAppController/rawRead.html:1:1:2:9 | {{raw .Foo}}\n{{.Bar}}\n | instantiated as a raw template | -| examples/booking/app/init.go:36:44:36:53 | selection of Path | examples/booking/app/init.go:36:44:36:48 | selection of URL : pointer type | examples/booking/app/init.go:36:44:36:53 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:36:44:36:48 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | -| examples/booking/app/init.go:40:49:40:58 | selection of Path | examples/booking/app/init.go:40:49:40:53 | selection of URL : pointer type | examples/booking/app/init.go:40:49:40:58 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:40:49:40:53 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | +| EndToEnd.go:37:24:37:26 | buf | EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:37:24:37:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:36:18:36:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | +| EndToEnd.go:69:22:69:51 | call to Get | EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:69:22:69:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | +| Revel.go:70:22:70:35 | selection of Query | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | Cross-site scripting vulnerability due to $@. The value is $@. | Revel.go:70:22:70:29 | selection of Params | user-provided value | views/myAppController/rawRead.html:1:1:2:9 | {{raw .Foo}}\n{{.Bar}}\n | instantiated as a raw template | +| examples/booking/app/init.go:36:44:36:53 | selection of Path | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:36:44:36:48 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | +| examples/booking/app/init.go:40:49:40:58 | selection of Path | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:40:49:40:53 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected index fc24c4a73ca..5cce1e37d95 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected @@ -1,24 +1,12 @@ edges -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:25 | implicit dereference : Params | -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | EndToEnd.go:58:18:58:47 | call to Get | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:25 | implicit dereference : Params | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:47 | call to Get | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:33 | implicit dereference : Params | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | EndToEnd.go:64:26:64:55 | call to Get | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:33 | implicit dereference : Params | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:55 | call to Get | +| EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:47 | call to Get | +| EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:55 | call to Get | nodes -| EndToEnd.go:58:18:58:25 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| EndToEnd.go:58:18:58:25 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| EndToEnd.go:58:18:58:25 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:58:18:58:47 | call to Get | semmle.label | call to Get | -| EndToEnd.go:64:26:64:33 | implicit dereference : Params | semmle.label | implicit dereference : Params | -| EndToEnd.go:64:26:64:33 | selection of Params : pointer type | semmle.label | selection of Params : pointer type | +| EndToEnd.go:64:26:64:33 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get | subpaths #select -| EndToEnd.go:58:18:58:47 | call to Get | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:47 | call to Get | This path depends on a $@. | EndToEnd.go:58:18:58:25 | selection of Params | user-provided value | -| EndToEnd.go:64:26:64:55 | call to Get | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:55 | call to Get | This path depends on a $@. | EndToEnd.go:64:26:64:33 | selection of Params | user-provided value | +| EndToEnd.go:58:18:58:47 | call to Get | EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:47 | call to Get | This path depends on a $@. | EndToEnd.go:58:18:58:25 | selection of Params | user-provided value | +| EndToEnd.go:64:26:64:55 | call to Get | EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:55 | call to Get | This path depends on a $@. | EndToEnd.go:64:26:64:33 | selection of Params | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/go.mod b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/go.mod new file mode 100644 index 00000000000..1ac3796ab52 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/go.mod @@ -0,0 +1,26 @@ +module main + +go 1.19 + +require github.com/gogf/gf v1.16.9 + +require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 // indirect + github.com/fatih/color v1.12.0 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/gomodule/redigo v1.8.5 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/grokify/html-strip-tags-go v0.0.1 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + go.opentelemetry.io/otel v1.0.0 // indirect + go.opentelemetry.io/otel/trace v1.0.0 // indirect + golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect + golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected new file mode 100644 index 00000000000..f4e3e4f15b0 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.expected @@ -0,0 +1,47 @@ +| gogf.go:12:9:12:11 | sql | +| gogf.go:13:11:13:13 | sql | +| gogf.go:14:13:14:15 | sql | +| gogf.go:15:13:15:15 | sql | +| gogf.go:16:11:16:13 | sql | +| gogf.go:17:13:17:15 | sql | +| gogf.go:18:12:18:14 | sql | +| gogf.go:19:10:19:12 | sql | +| gogf.go:20:8:20:10 | sql | +| gogf.go:21:17:21:19 | sql | +| gogf.go:22:19:22:21 | sql | +| gogf.go:23:20:23:22 | sql | +| gogf.go:24:23:24:25 | sql | +| gogf.go:25:21:25:23 | sql | +| gogf.go:26:23:26:25 | sql | +| gogf.go:27:22:27:24 | sql | +| gogf.go:28:24:28:26 | sql | +| gogf.go:32:9:32:11 | sql | +| gogf.go:33:11:33:13 | sql | +| gogf.go:34:13:34:15 | sql | +| gogf.go:35:13:35:15 | sql | +| gogf.go:36:11:36:13 | sql | +| gogf.go:37:13:37:15 | sql | +| gogf.go:38:12:38:14 | sql | +| gogf.go:39:10:39:12 | sql | +| gogf.go:40:8:40:10 | sql | +| gogf.go:41:17:41:19 | sql | +| gogf.go:42:23:42:25 | sql | +| gogf.go:43:21:43:23 | sql | +| gogf.go:44:23:44:25 | sql | +| gogf.go:45:22:45:24 | sql | +| gogf.go:46:24:46:26 | sql | +| gogf.go:51:9:51:11 | sql | +| gogf.go:52:11:52:13 | sql | +| gogf.go:53:13:53:15 | sql | +| gogf.go:54:13:54:15 | sql | +| gogf.go:55:11:55:13 | sql | +| gogf.go:56:13:56:15 | sql | +| gogf.go:57:12:57:14 | sql | +| gogf.go:58:10:58:12 | sql | +| gogf.go:59:8:59:10 | sql | +| gogf.go:60:17:60:19 | sql | +| gogf.go:61:23:61:25 | sql | +| gogf.go:62:21:62:23 | sql | +| gogf.go:63:23:63:25 | sql | +| gogf.go:64:22:64:24 | sql | +| gogf.go:65:24:65:26 | sql | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go new file mode 100644 index 00000000000..d0eceaf862c --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.go @@ -0,0 +1,70 @@ +package main + +//go:generate depstubber -vendor github.com/gogf/gf/frame/g "" DB +//go:generate depstubber -vendor github.com/gogf/gf/database/gdb DB,Core,TX "" + +import ( + "github.com/gogf/gf/database/gdb" + "github.com/gogf/gf/frame/g" +) + +func gogfCoreTest(sql string, c *gdb.Core) { + c.Exec(sql, nil) // $ querystring=sql + c.GetAll(sql, nil) // $ querystring=sql + c.GetArray(sql, nil) // $ querystring=sql + c.GetCount(sql, nil) // $ querystring=sql + c.GetOne(sql, nil) // $ querystring=sql + c.GetValue(sql, nil) // $ querystring=sql + c.Prepare(sql, true) // $ querystring=sql + c.Query(sql, nil) // $ querystring=sql + c.Raw(sql, nil) // $ querystring=sql + c.GetScan(nil, sql, nil) // $ querystring=sql + c.GetStruct(nil, sql, nil) // $ querystring=sql + c.GetStructs(nil, sql, nil) // $ querystring=sql + c.DoCommit(nil, nil, sql, nil) // $ querystring=sql + c.DoExec(nil, nil, sql, nil) // $ querystring=sql + c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql + c.DoQuery(nil, nil, sql, nil) // $ querystring=sql + c.DoPrepare(nil, nil, sql) // $ querystring=sql +} + +func gogfDbtest(sql string, c gdb.DB) { + c.Exec(sql, nil) // $ querystring=sql + c.GetAll(sql, nil) // $ querystring=sql + c.GetArray(sql, nil) // $ querystring=sql + c.GetCount(sql, nil) // $ querystring=sql + c.GetOne(sql, nil) // $ querystring=sql + c.GetValue(sql, nil) // $ querystring=sql + c.Prepare(sql, true) // $ querystring=sql + c.Query(sql, nil) // $ querystring=sql + c.Raw(sql, nil) // $ querystring=sql + c.GetScan(nil, sql, nil) // $ querystring=sql + c.DoCommit(nil, nil, sql, nil) // $ querystring=sql + c.DoExec(nil, nil, sql, nil) // $ querystring=sql + c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql + c.DoQuery(nil, nil, sql, nil) // $ querystring=sql + c.DoPrepare(nil, nil, sql) // $ querystring=sql +} + +func gogfGTest(sql string) { + c := g.DB("ad") + c.Exec(sql, nil) // $ querystring=sql + c.GetAll(sql, nil) // $ querystring=sql + c.GetArray(sql, nil) // $ querystring=sql + c.GetCount(sql, nil) // $ querystring=sql + c.GetOne(sql, nil) // $ querystring=sql + c.GetValue(sql, nil) // $ querystring=sql + c.Prepare(sql, true) // $ querystring=sql + c.Query(sql, nil) // $ querystring=sql + c.Raw(sql, nil) // $ querystring=sql + c.GetScan(nil, sql, nil) // $ querystring=sql + c.DoCommit(nil, nil, sql, nil) // $ querystring=sql + c.DoExec(nil, nil, sql, nil) // $ querystring=sql + c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql + c.DoQuery(nil, nil, sql, nil) // $ querystring=sql + c.DoPrepare(nil, nil, sql) // $ querystring=sql +} + +func main() { + return +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql new file mode 100644 index 00000000000..7b56fd97441 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/gogf.ql @@ -0,0 +1,4 @@ +import go + +from SQL::QueryString qs +select qs diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/database/gdb/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/database/gdb/stub.go new file mode 100644 index 00000000000..4eef94f8893 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/database/gdb/stub.go @@ -0,0 +1,1175 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gogf/gf/database/gdb, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gogf/gf/database/gdb (exports: DB,Core,TX; functions: ) + +// Package gdb is a stub of github.com/gogf/gf/database/gdb, generated by depstubber. +package gdb + +import ( + context "context" + sql "database/sql" + time "time" +) + +type ChunkHandler func(Result, error) bool + +type ConfigNode struct { + Host string + Port string + User string + Pass string + Name string + Type string + Link string + Role string + Debug bool + Prefix string + DryRun bool + Weight int + Charset string + Timezone string + MaxIdleConnCount int + MaxOpenConnCount int + MaxConnLifeTime time.Duration + QueryTimeout time.Duration + ExecTimeout time.Duration + TranTimeout time.Duration + PrepareTimeout time.Duration + CreatedAt string + UpdatedAt string + DeletedAt string + TimeMaintainDisabled bool + CtxStrict bool +} + +func (_ *ConfigNode) String() string { + return "" +} + +type Core struct{} + +func (_ *Core) Begin() (*TX, error) { + return nil, nil +} + +func (_ *Core) Close(_ context.Context) error { + return nil +} + +func (_ *Core) Ctx(_ context.Context) DB { + return nil +} + +func (_ *Core) Delete(_ string, _ interface{}, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) DoCommit(_ context.Context, _ Link, _ string, _ []interface{}) (string, []interface{}, error) { + return "", nil, nil +} + +func (_ *Core) DoDelete(_ context.Context, _ Link, _ string, _ string, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) DoExec(_ context.Context, _ Link, _ string, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) DoGetAll(_ context.Context, _ Link, _ string, _ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *Core) DoInsert(_ context.Context, _ Link, _ string, _ []map[string]interface{}, _ DoInsertOption) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) DoPrepare(_ context.Context, _ Link, _ string) (*Stmt, error) { + return nil, nil +} + +func (_ *Core) DoQuery(_ context.Context, _ Link, _ string, _ ...interface{}) (*sql.Rows, error) { + return nil, nil +} + +func (_ *Core) DoUpdate(_ context.Context, _ Link, _ string, _ interface{}, _ string, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) Exec(_ string, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) GetAll(_ string, _ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *Core) GetArray(_ string, _ ...interface{}) ([]interface{}, error) { + return nil, nil +} + +func (_ *Core) GetCache() interface{} { + return nil +} + +func (_ *Core) GetChars() (string, string) { + return "", "" +} + +func (_ *Core) GetConfig() *ConfigNode { + return nil +} + +func (_ *Core) GetCore() *Core { + return nil +} + +func (_ *Core) GetCount(_ string, _ ...interface{}) (int, error) { + return 0, nil +} + +func (_ *Core) GetCtx() context.Context { + return nil +} + +func (_ *Core) GetCtxTimeout(_ int, _ context.Context) (context.Context, context.CancelFunc) { + return nil, nil +} + +func (_ *Core) GetDebug() bool { + return false +} + +func (_ *Core) GetDryRun() bool { + return false +} + +func (_ *Core) GetGroup() string { + return "" +} + +func (_ *Core) GetLogger() interface{} { + return nil +} + +func (_ *Core) GetOne(_ string, _ ...interface{}) (Record, error) { + return nil, nil +} + +func (_ *Core) GetPrefix() string { + return "" +} + +func (_ *Core) GetScan(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *Core) GetSchema() string { + return "" +} + +func (_ *Core) GetStruct(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *Core) GetStructs(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *Core) GetValue(_ string, _ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *Core) HasTable(_ string) (bool, error) { + return false, nil +} + +func (_ *Core) Insert(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) InsertAndGetId(_ string, _ interface{}, _ ...int) (int64, error) { + return 0, nil +} + +func (_ *Core) InsertIgnore(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) MarshalJSON() ([]byte, error) { + return nil, nil +} + +func (_ *Core) Master(_ ...string) (*sql.DB, error) { + return nil, nil +} + +func (_ *Core) MasterLink(_ ...string) (Link, error) { + return nil, nil +} + +func (_ *Core) Model(_ ...interface{}) *Model { + return nil +} + +func (_ *Core) PingMaster() error { + return nil +} + +func (_ *Core) PingSlave() error { + return nil +} + +func (_ *Core) Prepare(_ string, _ ...bool) (*Stmt, error) { + return nil, nil +} + +func (_ *Core) Query(_ string, _ ...interface{}) (*sql.Rows, error) { + return nil, nil +} + +func (_ *Core) QuotePrefixTableName(_ string) string { + return "" +} + +func (_ *Core) QuoteString(_ string) string { + return "" +} + +func (_ *Core) QuoteWord(_ string) string { + return "" +} + +func (_ *Core) Raw(_ string, _ ...interface{}) *Model { + return nil +} + +func (_ *Core) Replace(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) Save(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) Schema(_ string) *Schema { + return nil +} + +func (_ *Core) SetDebug(_ bool) {} + +func (_ *Core) SetDryRun(_ bool) {} + +func (_ *Core) SetLogger(_ interface{}) {} + +func (_ *Core) SetMaxConnLifeTime(_ time.Duration) {} + +func (_ *Core) SetMaxIdleConnCount(_ int) {} + +func (_ *Core) SetMaxOpenConnCount(_ int) {} + +func (_ *Core) SetSchema(_ string) {} + +func (_ *Core) Slave(_ ...string) (*sql.DB, error) { + return nil, nil +} + +func (_ *Core) SlaveLink(_ ...string) (Link, error) { + return nil, nil +} + +func (_ *Core) Table(_ ...interface{}) *Model { + return nil +} + +func (_ *Core) TableFields(_ string, _ ...string) (map[string]*TableField, error) { + return nil, nil +} + +func (_ *Core) Tables(_ ...string) ([]string, error) { + return nil, nil +} + +func (_ *Core) Transaction(_ context.Context, _ func(context.Context, *TX) error) error { + return nil +} + +func (_ *Core) Union(_ ...*Model) *Model { + return nil +} + +func (_ *Core) UnionAll(_ ...*Model) *Model { + return nil +} + +func (_ *Core) Update(_ string, _ interface{}, _ interface{}, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Core) With(_ ...interface{}) *Model { + return nil +} + +type DB interface { + Begin() (*TX, error) + Close(_ context.Context) error + Ctx(_ context.Context) DB + Delete(_ string, _ interface{}, _ ...interface{}) (sql.Result, error) + DoCommit(_ context.Context, _ Link, _ string, _ []interface{}) (string, []interface{}, error) + DoDelete(_ context.Context, _ Link, _ string, _ string, _ ...interface{}) (sql.Result, error) + DoExec(_ context.Context, _ Link, _ string, _ ...interface{}) (sql.Result, error) + DoGetAll(_ context.Context, _ Link, _ string, _ ...interface{}) (Result, error) + DoInsert(_ context.Context, _ Link, _ string, _ []map[string]interface{}, _ DoInsertOption) (sql.Result, error) + DoPrepare(_ context.Context, _ Link, _ string) (*Stmt, error) + DoQuery(_ context.Context, _ Link, _ string, _ ...interface{}) (*sql.Rows, error) + DoUpdate(_ context.Context, _ Link, _ string, _ interface{}, _ string, _ ...interface{}) (sql.Result, error) + Exec(_ string, _ ...interface{}) (sql.Result, error) + FilteredLink() string + GetAll(_ string, _ ...interface{}) (Result, error) + GetArray(_ string, _ ...interface{}) ([]interface{}, error) + GetCache() interface{} + GetChars() (string, string) + GetConfig() *ConfigNode + GetCore() *Core + GetCount(_ string, _ ...interface{}) (int, error) + GetCtx() context.Context + GetDebug() bool + GetDryRun() bool + GetGroup() string + GetLogger() interface{} + GetOne(_ string, _ ...interface{}) (Record, error) + GetPrefix() string + GetScan(_ interface{}, _ string, _ ...interface{}) error + GetSchema() string + GetValue(_ string, _ ...interface{}) (interface{}, error) + Insert(_ string, _ interface{}, _ ...int) (sql.Result, error) + InsertAndGetId(_ string, _ interface{}, _ ...int) (int64, error) + InsertIgnore(_ string, _ interface{}, _ ...int) (sql.Result, error) + Master(_ ...string) (*sql.DB, error) + Model(_ ...interface{}) *Model + Open(_ *ConfigNode) (*sql.DB, error) + PingMaster() error + PingSlave() error + Prepare(_ string, _ ...bool) (*Stmt, error) + Query(_ string, _ ...interface{}) (*sql.Rows, error) + Raw(_ string, _ ...interface{}) *Model + Replace(_ string, _ interface{}, _ ...int) (sql.Result, error) + Save(_ string, _ interface{}, _ ...int) (sql.Result, error) + Schema(_ string) *Schema + SetDebug(_ bool) + SetDryRun(_ bool) + SetLogger(_ interface{}) + SetMaxConnLifeTime(_ time.Duration) + SetMaxIdleConnCount(_ int) + SetMaxOpenConnCount(_ int) + SetSchema(_ string) + Slave(_ ...string) (*sql.DB, error) + Table(_ ...interface{}) *Model + TableFields(_ context.Context, _ string, _ ...string) (map[string]*TableField, error) + Tables(_ context.Context, _ ...string) ([]string, error) + Transaction(_ context.Context, _ func(context.Context, *TX) error) error + Union(_ ...*Model) *Model + UnionAll(_ ...*Model) *Model + Update(_ string, _ interface{}, _ interface{}, _ ...interface{}) (sql.Result, error) + With(_ ...interface{}) *Model +} + +type DoInsertOption struct { + OnDuplicateStr string + OnDuplicateMap map[string]interface{} + InsertOption int + BatchCount int +} + +type Link interface { + Exec(_ string, _ ...interface{}) (sql.Result, error) + ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error) + IsTransaction() bool + Prepare(_ string) (*sql.Stmt, error) + PrepareContext(_ context.Context, _ string) (*sql.Stmt, error) + Query(_ string, _ ...interface{}) (*sql.Rows, error) + QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error) +} + +type Model struct{} + +func (_ *Model) All(_ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *Model) And(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) Args(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) Array(_ ...interface{}) ([]interface{}, error) { + return nil, nil +} + +func (_ *Model) As(_ string) *Model { + return nil +} + +func (_ *Model) Avg(_ string) (float64, error) { + return 0, nil +} + +func (_ *Model) Batch(_ int) *Model { + return nil +} + +func (_ *Model) Cache(_ time.Duration, _ ...string) *Model { + return nil +} + +func (_ *Model) Chunk(_ int, _ ChunkHandler) {} + +func (_ *Model) Clone() *Model { + return nil +} + +func (_ *Model) Count(_ ...interface{}) (int, error) { + return 0, nil +} + +func (_ *Model) CountColumn(_ string) (int, error) { + return 0, nil +} + +func (_ *Model) Ctx(_ context.Context) *Model { + return nil +} + +func (_ *Model) DB(_ DB) *Model { + return nil +} + +func (_ *Model) Data(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) Decrement(_ string, _ interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) Delete(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) Distinct() *Model { + return nil +} + +func (_ *Model) FieldAvg(_ string, _ ...string) *Model { + return nil +} + +func (_ *Model) FieldCount(_ string, _ ...string) *Model { + return nil +} + +func (_ *Model) FieldMax(_ string, _ ...string) *Model { + return nil +} + +func (_ *Model) FieldMin(_ string, _ ...string) *Model { + return nil +} + +func (_ *Model) FieldSum(_ string, _ ...string) *Model { + return nil +} + +func (_ *Model) Fields(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) FieldsEx(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) FieldsExStr(_ string, _ ...string) string { + return "" +} + +func (_ *Model) FieldsStr(_ ...string) string { + return "" +} + +func (_ *Model) Filter() *Model { + return nil +} + +func (_ *Model) FindAll(_ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *Model) FindArray(_ ...interface{}) ([]interface{}, error) { + return nil, nil +} + +func (_ *Model) FindCount(_ ...interface{}) (int, error) { + return 0, nil +} + +func (_ *Model) FindOne(_ ...interface{}) (Record, error) { + return nil, nil +} + +func (_ *Model) FindScan(_ interface{}, _ ...interface{}) error { + return nil +} + +func (_ *Model) FindValue(_ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *Model) ForPage(_ int, _ int) *Model { + return nil +} + +func (_ *Model) GetCtx() context.Context { + return nil +} + +func (_ *Model) GetFieldsExStr(_ string, _ ...string) string { + return "" +} + +func (_ *Model) GetFieldsStr(_ ...string) string { + return "" +} + +func (_ *Model) Group(_ ...string) *Model { + return nil +} + +func (_ *Model) GroupBy(_ string) *Model { + return nil +} + +func (_ *Model) Handler(_ ...ModelHandler) *Model { + return nil +} + +func (_ *Model) HasField(_ string) (bool, error) { + return false, nil +} + +func (_ *Model) Having(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) Increment(_ string, _ interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) InnerJoin(_ ...string) *Model { + return nil +} + +func (_ *Model) Insert(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) InsertAndGetId(_ ...interface{}) (int64, error) { + return 0, nil +} + +func (_ *Model) InsertIgnore(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) LeftJoin(_ ...string) *Model { + return nil +} + +func (_ *Model) Limit(_ ...int) *Model { + return nil +} + +func (_ *Model) LockShared() *Model { + return nil +} + +func (_ *Model) LockUpdate() *Model { + return nil +} + +func (_ *Model) Master() *Model { + return nil +} + +func (_ *Model) Max(_ string) (float64, error) { + return 0, nil +} + +func (_ *Model) Min(_ string) (float64, error) { + return 0, nil +} + +func (_ *Model) Offset(_ int) *Model { + return nil +} + +func (_ *Model) OmitEmpty() *Model { + return nil +} + +func (_ *Model) OmitEmptyData() *Model { + return nil +} + +func (_ *Model) OmitEmptyWhere() *Model { + return nil +} + +func (_ *Model) OmitNil() *Model { + return nil +} + +func (_ *Model) OmitNilData() *Model { + return nil +} + +func (_ *Model) OmitNilWhere() *Model { + return nil +} + +func (_ *Model) OnDuplicate(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) OnDuplicateEx(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) One(_ ...interface{}) (Record, error) { + return nil, nil +} + +func (_ *Model) Option(_ int) *Model { + return nil +} + +func (_ *Model) Or(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) Order(_ ...string) *Model { + return nil +} + +func (_ *Model) OrderAsc(_ string) *Model { + return nil +} + +func (_ *Model) OrderBy(_ string) *Model { + return nil +} + +func (_ *Model) OrderDesc(_ string) *Model { + return nil +} + +func (_ *Model) OrderRandom() *Model { + return nil +} + +func (_ *Model) Page(_ int, _ int) *Model { + return nil +} + +func (_ *Model) Raw(_ string, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) Replace(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) RightJoin(_ ...string) *Model { + return nil +} + +func (_ *Model) Safe(_ ...bool) *Model { + return nil +} + +func (_ *Model) Save(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) Scan(_ interface{}, _ ...interface{}) error { + return nil +} + +func (_ *Model) ScanList(_ interface{}, _ string, _ ...string) error { + return nil +} + +func (_ *Model) Schema(_ string) *Model { + return nil +} + +func (_ *Model) Select(_ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *Model) Slave() *Model { + return nil +} + +func (_ *Model) Struct(_ interface{}, _ ...interface{}) error { + return nil +} + +func (_ *Model) Structs(_ interface{}, _ ...interface{}) error { + return nil +} + +func (_ *Model) Sum(_ string) (float64, error) { + return 0, nil +} + +func (_ *Model) TX(_ *TX) *Model { + return nil +} + +func (_ *Model) TableFields(_ string, _ ...string) (map[string]*TableField, error) { + return nil, nil +} + +func (_ *Model) Transaction(_ context.Context, _ func(context.Context, *TX) error) error { + return nil +} + +func (_ *Model) Union(_ ...*Model) *Model { + return nil +} + +func (_ *Model) UnionAll(_ ...*Model) *Model { + return nil +} + +func (_ *Model) Unscoped() *Model { + return nil +} + +func (_ *Model) Update(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Model) Value(_ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *Model) Where(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) WhereBetween(_ string, _ interface{}, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereGT(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereGTE(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereIn(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereLT(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereLTE(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereLike(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereNot(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereNotBetween(_ string, _ interface{}, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereNotIn(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereNotLike(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereNotNull(_ ...string) *Model { + return nil +} + +func (_ *Model) WhereNull(_ ...string) *Model { + return nil +} + +func (_ *Model) WhereOr(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrBetween(_ string, _ interface{}, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrGT(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrGTE(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrIn(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrLT(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrLTE(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrLike(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrNotBetween(_ string, _ interface{}, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrNotIn(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrNotLike(_ string, _ interface{}) *Model { + return nil +} + +func (_ *Model) WhereOrNotNull(_ ...string) *Model { + return nil +} + +func (_ *Model) WhereOrNull(_ ...string) *Model { + return nil +} + +func (_ *Model) WhereOrf(_ string, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) WherePri(_ interface{}, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) Wheref(_ string, _ ...interface{}) *Model { + return nil +} + +func (_ *Model) With(_ ...interface{}) *Model { + return nil +} + +func (_ *Model) WithAll() *Model { + return nil +} + +type ModelHandler func(*Model) *Model + +type Record map[string]interface{} + +func (_ Record) GMap() interface{} { + return nil +} + +func (_ Record) Interface() interface{} { + return nil +} + +func (_ Record) IsEmpty() bool { + return false +} + +func (_ Record) Json() string { + return "" +} + +func (_ Record) Map() map[string]interface{} { + return nil +} + +func (_ Record) Struct(_ interface{}) error { + return nil +} + +func (_ Record) Xml(_ ...string) string { + return "" +} + +type Result []Record + +func (_ Result) Array(_ ...string) []interface{} { + return nil +} + +func (_ Result) Chunk(_ int) []Result { + return nil +} + +func (_ Result) Interface() interface{} { + return nil +} + +func (_ Result) IsEmpty() bool { + return false +} + +func (_ Result) Json() string { + return "" +} + +func (_ Result) Len() int { + return 0 +} + +func (_ Result) List() []map[string]interface{} { + return nil +} + +func (_ Result) MapKeyInt(_ string) map[int]map[string]interface{} { + return nil +} + +func (_ Result) MapKeyStr(_ string) map[string]map[string]interface{} { + return nil +} + +func (_ Result) MapKeyUint(_ string) map[uint]map[string]interface{} { + return nil +} + +func (_ Result) MapKeyValue(_ string) map[string]interface{} { + return nil +} + +func (_ Result) RecordKeyInt(_ string) map[int]Record { + return nil +} + +func (_ Result) RecordKeyStr(_ string) map[string]Record { + return nil +} + +func (_ Result) RecordKeyUint(_ string) map[uint]Record { + return nil +} + +func (_ Result) ScanList(_ interface{}, _ string, _ ...string) error { + return nil +} + +func (_ Result) Size() int { + return 0 +} + +func (_ Result) Structs(_ interface{}) error { + return nil +} + +func (_ Result) Xml(_ ...string) string { + return "" +} + +type Schema struct{} + +func (_ *Schema) Model(_ string) *Model { + return nil +} + +func (_ *Schema) Table(_ string) *Model { + return nil +} + +type Stmt struct { + Stmt *sql.Stmt +} + +func (_ *Stmt) Close() error { + return nil +} + +func (_ *Stmt) Exec(_ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Stmt) ExecContext(_ context.Context, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *Stmt) Query(_ ...interface{}) (*sql.Rows, error) { + return nil, nil +} + +func (_ *Stmt) QueryContext(_ context.Context, _ ...interface{}) (*sql.Rows, error) { + return nil, nil +} + +func (_ *Stmt) QueryRow(_ ...interface{}) *sql.Row { + return nil +} + +func (_ *Stmt) QueryRowContext(_ context.Context, _ ...interface{}) *sql.Row { + return nil +} + +type TX struct{} + +func (_ *TX) Begin() error { + return nil +} + +func (_ *TX) Commit() error { + return nil +} + +func (_ *TX) Ctx(_ context.Context) *TX { + return nil +} + +func (_ *TX) Delete(_ string, _ interface{}, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) Exec(_ string, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) GetAll(_ string, _ ...interface{}) (Result, error) { + return nil, nil +} + +func (_ *TX) GetCount(_ string, _ ...interface{}) (int, error) { + return 0, nil +} + +func (_ *TX) GetOne(_ string, _ ...interface{}) (Record, error) { + return nil, nil +} + +func (_ *TX) GetScan(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *TX) GetStruct(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *TX) GetStructs(_ interface{}, _ string, _ ...interface{}) error { + return nil +} + +func (_ *TX) GetValue(_ string, _ ...interface{}) (interface{}, error) { + return nil, nil +} + +func (_ *TX) Insert(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) InsertAndGetId(_ string, _ interface{}, _ ...int) (int64, error) { + return 0, nil +} + +func (_ *TX) InsertIgnore(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) IsClosed() bool { + return false +} + +func (_ *TX) Model(_ ...interface{}) *Model { + return nil +} + +func (_ *TX) Prepare(_ string) (*Stmt, error) { + return nil, nil +} + +func (_ *TX) Query(_ string, _ ...interface{}) (*sql.Rows, error) { + return nil, nil +} + +func (_ *TX) Raw(_ string, _ ...interface{}) *Model { + return nil +} + +func (_ *TX) Replace(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) Rollback() error { + return nil +} + +func (_ *TX) RollbackTo(_ string) error { + return nil +} + +func (_ *TX) Save(_ string, _ interface{}, _ ...int) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) SavePoint(_ string) error { + return nil +} + +func (_ *TX) Schema(_ string) *Schema { + return nil +} + +func (_ *TX) Transaction(_ context.Context, _ func(context.Context, *TX) error) error { + return nil +} + +func (_ *TX) Update(_ string, _ interface{}, _ interface{}, _ ...interface{}) (sql.Result, error) { + return nil, nil +} + +func (_ *TX) With(_ interface{}) *Model { + return nil +} + +type TableField struct { + Index int + Name string + Type string + Null bool + Key string + Default interface{} + Extra string + Comment string +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/frame/g/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/frame/g/stub.go new file mode 100644 index 00000000000..6bb8a96631f --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/github.com/gogf/gf/frame/g/stub.go @@ -0,0 +1,14 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gogf/gf/frame/g, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gogf/gf/frame/g (exports: ; functions: DB) + +// Package g is a stub of github.com/gogf/gf/frame/g, generated by depstubber. +package g + +import "github.com/gogf/gf/database/gdb" + +func DB(_ ...string) gdb.DB { + return nil +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/modules.txt new file mode 100644 index 00000000000..72560d0da5e --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/vendor/modules.txt @@ -0,0 +1,57 @@ +# github.com/gogf/gf v1.16.9 +## explicit +github.com/gogf/gf +# github.com/BurntSushi/toml v0.3.1 +## explicit +github.com/BurntSushi/toml +# github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 +## explicit +github.com/clbanning/mxj +# github.com/fatih/color v1.12.0 +## explicit +github.com/fatih/color +# github.com/fsnotify/fsnotify v1.4.9 +## explicit +github.com/fsnotify/fsnotify +# github.com/go-sql-driver/mysql v1.6.0 +## explicit +github.com/go-sql-driver/mysql +# github.com/gomodule/redigo v1.8.5 +## explicit +github.com/gomodule/redigo +# github.com/gorilla/websocket v1.4.2 +## explicit +github.com/gorilla/websocket +# github.com/grokify/html-strip-tags-go v0.0.1 +## explicit +github.com/grokify/html-strip-tags-go +# github.com/mattn/go-colorable v0.1.8 +## explicit +github.com/mattn/go-colorable +# github.com/mattn/go-isatty v0.0.12 +## explicit +github.com/mattn/go-isatty +# github.com/mattn/go-runewidth v0.0.9 +## explicit +github.com/mattn/go-runewidth +# github.com/olekukonko/tablewriter v0.0.5 +## explicit +github.com/olekukonko/tablewriter +# go.opentelemetry.io/otel v1.0.0 +## explicit +go.opentelemetry.io/otel +# go.opentelemetry.io/otel/trace v1.0.0 +## explicit +go.opentelemetry.io/otel/trace +# golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 +## explicit +golang.org/x/net +# golang.org/x/sys v0.0.0-20210423082822-04245dca01da +## explicit +golang.org/x/sys +# golang.org/x/text v0.3.6 +## explicit +golang.org/x/text +# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b +## explicit +gopkg.in/yaml.v3 diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod new file mode 100644 index 00000000000..1f243775658 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/go.mod @@ -0,0 +1,5 @@ +module main + +go 1.18 + +require github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6 diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected new file mode 100644 index 00000000000..cbd8166ea5e --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.expected @@ -0,0 +1,6 @@ +| gorqlite.go:11:13:11:16 | sqls | +| gorqlite.go:12:13:12:16 | sqls | +| gorqlite.go:13:13:13:16 | sqls | +| gorqlite.go:14:16:14:18 | sql | +| gorqlite.go:15:16:15:18 | sql | +| gorqlite.go:16:16:16:18 | sql | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go new file mode 100644 index 00000000000..9b60c6684e6 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.go @@ -0,0 +1,20 @@ +package main + +//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection Open + +import ( + "github.com/rqlite/gorqlite" +) + +func gorqlitetest(sql string, sqls []string) { + conn, _ := gorqlite.Open("dbUrl") + conn.Query(sqls) // $ querystring=sqls + conn.Queue(sqls) // $ querystring=sqls + conn.Write(sqls) // $ querystring=sqls + conn.QueryOne(sql) // $ querystring=sql + conn.QueueOne(sql) // $ querystring=sql + conn.WriteOne(sql) // $ querystring=sql +} +func main() { + return +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql new file mode 100644 index 00000000000..7b56fd97441 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/gorqlite.ql @@ -0,0 +1,4 @@ +import go + +from SQL::QueryString qs +select qs diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go new file mode 100644 index 00000000000..f6f4ca18ec1 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/github.com/rqlite/gorqlite/stub.go @@ -0,0 +1,102 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/rqlite/gorqlite, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/rqlite/gorqlite (exports: Connection; functions: Open) + +// Package gorqlite is a stub of github.com/rqlite/gorqlite, generated by depstubber. +package gorqlite + +type Connection struct { + ID string +} + +func (_ *Connection) Close() {} + +func (_ *Connection) ConsistencyLevel() (string, error) { + return "", nil +} + +func (_ *Connection) Leader() (string, error) { + return "", nil +} + +func (_ *Connection) Peers() ([]string, error) { + return nil, nil +} + +func (_ *Connection) Query(_ []string) ([]QueryResult, error) { + return nil, nil +} + +func (_ *Connection) QueryOne(_ string) (QueryResult, error) { + return QueryResult{}, nil +} + +func (_ *Connection) Queue(_ []string) (int64, error) { + return 0, nil +} + +func (_ *Connection) QueueOne(_ string) (int64, error) { + return 0, nil +} + +func (_ *Connection) SetConsistencyLevel(_ string) error { + return nil +} + +func (_ *Connection) SetExecutionWithTransaction(_ bool) error { + return nil +} + +func (_ *Connection) Write(_ []string) ([]WriteResult, error) { + return nil, nil +} + +func (_ *Connection) WriteOne(_ string) (WriteResult, error) { + return WriteResult{}, nil +} + +func Open(_ string) (Connection, error) { + return Connection{}, nil +} + +type QueryResult struct { + Err error + Timing float64 +} + +func (_ *QueryResult) Columns() []string { + return nil +} + +func (_ *QueryResult) Map() (map[string]interface{}, error) { + return nil, nil +} + +func (_ *QueryResult) Next() bool { + return false +} + +func (_ *QueryResult) NumRows() int64 { + return 0 +} + +func (_ *QueryResult) RowNumber() int64 { + return 0 +} + +func (_ *QueryResult) Scan(_ ...interface{}) error { + return nil +} + +func (_ *QueryResult) Types() []string { + return nil +} + +type WriteResult struct { + Err error + Timing float64 + RowsAffected int64 + LastInsertID int64 +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt new file mode 100644 index 00000000000..f5e5b9989ed --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/vendor/modules.txt @@ -0,0 +1,3 @@ +# github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6 +## explicit +github.com/rqlite/gorqlite diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Spew/TaintFlows.expected b/go/ql/test/library-tests/semmle/go/frameworks/Spew/TaintFlows.expected index f24231f8566..404524ec3d6 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Spew/TaintFlows.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Spew/TaintFlows.expected @@ -1,17 +1,17 @@ -| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:33:14:33:23 | sUntrusted | -| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:35:14:35:23 | sUntrusted | -| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:41:18:41:27 | sUntrusted | -| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:51:13:51:16 | str3 | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:30:12:30:21 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:31:13:31:22 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:32:15:32:24 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:34:17:34:26 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:36:17:36:26 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:38:16:38:25 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:39:17:39:26 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:40:19:40:28 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:42:21:42:30 | pUntrusted | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:45:13:45:16 | str1 | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:48:13:48:16 | str2 | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:54:13:54:16 | str4 | -| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:57:13:57:16 | str5 | +| test.go:26:16:26:35 | call to getUntrustedString | test.go:33:14:33:23 | sUntrusted | +| test.go:26:16:26:35 | call to getUntrustedString | test.go:35:14:35:23 | sUntrusted | +| test.go:26:16:26:35 | call to getUntrustedString | test.go:41:18:41:27 | sUntrusted | +| test.go:26:16:26:35 | call to getUntrustedString | test.go:51:13:51:16 | str3 | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:30:12:30:21 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:31:13:31:22 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:32:15:32:24 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:34:17:34:26 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:36:17:36:26 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:38:16:38:25 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:39:17:39:26 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:40:19:40:28 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:42:21:42:30 | pUntrusted | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:45:13:45:16 | str1 | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:48:13:48:16 | str2 | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:54:13:54:16 | str4 | +| test.go:28:16:28:35 | call to getUntrustedStruct | test.go:57:13:57:16 | str5 | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql index bc41ecbd76e..8a3456691a9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/StdlibTaintFlow.ql @@ -13,13 +13,13 @@ class Link extends TaintTracking::FunctionModel { } } -predicate isSource(DataFlow::Node source, DataFlow::CallNode call) { +predicate callResultisSource(DataFlow::Node source, DataFlow::CallNode call) { exists(Function fn | fn.hasQualifiedName(_, "newSource") | call = fn.getACall() and source = call.getResult() ) } -predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { +predicate callArgumentisSink(DataFlow::Node sink, DataFlow::CallNode call) { exists(Function fn | fn.hasQualifiedName(_, "sink") | call = fn.getACall() and sink = call.getArgument(1) ) @@ -28,9 +28,9 @@ predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { class FlowConf extends TaintTracking::Configuration { FlowConf() { this = "FlowConf" } - override predicate isSource(DataFlow::Node source) { isSource(source, _) } + override predicate isSource(DataFlow::Node source) { callResultisSource(source, _) } - override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + override predicate isSink(DataFlow::Node sink) { callArgumentisSink(sink, _) } } /** @@ -43,8 +43,8 @@ predicate flowsToSink(DataFlow::CallNode sourceCall) { | cfg.hasFlowPath(source, sink) and ( - isSource(source.getNode(), sourceCall) and - isSink(sink.getNode(), sinkCall) and + callResultisSource(source.getNode(), sourceCall) and + callArgumentisSink(sink.getNode(), sinkCall) and sourceCall.getArgument(0).getIntValue() = sinkCall.getArgument(0).getIntValue() ) ) @@ -52,5 +52,5 @@ predicate flowsToSink(DataFlow::CallNode sourceCall) { /* Show only flow sources that DON'T flow to their dedicated sink. */ from DataFlow::CallNode sourceCall -where isSource(_, sourceCall) and not flowsToSink(sourceCall) +where callResultisSource(_, sourceCall) and not flowsToSink(sourceCall) select sourceCall, "No flow to its sink" diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index 8a4bf0b48ed..aa0daf2d591 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -1,79 +1,43 @@ edges -| test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:15:14:55 | type conversion | -| test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:42:14:47 | implicit dereference : Cookie | -| test.go:14:42:14:47 | implicit dereference : Cookie | test.go:14:15:14:55 | type conversion | -| test.go:14:42:14:47 | implicit dereference : Cookie | test.go:14:42:14:47 | implicit dereference : Cookie | -| test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:17:15:17:31 | type conversion | -| test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:17:22:17:25 | implicit dereference : Node | -| test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:28:22:28:25 | node | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:17:15:17:31 | type conversion | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:17:22:17:25 | implicit dereference : Node | -| test.go:17:22:17:25 | implicit dereference : Node | test.go:28:22:28:25 | node | -| test.go:19:36:19:47 | selection of Body : ReadCloser | test.go:20:15:20:32 | type conversion | -| test.go:19:36:19:47 | selection of Body : ReadCloser | test.go:20:22:20:26 | implicit dereference : Node | -| test.go:20:22:20:26 | implicit dereference : Node | test.go:20:15:20:32 | type conversion | -| test.go:20:22:20:26 | implicit dereference : Node | test.go:20:22:20:26 | implicit dereference : Node | -| test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:15:23:35 | type conversion | -| test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:22:23:29 | index expression : pointer type | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:15:23:35 | type conversion | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:23:22:23:29 | implicit dereference : Node | test.go:23:22:23:29 | index expression : pointer type | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:15:23:35 | type conversion | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:22:23:29 | implicit dereference : Node | -| test.go:23:22:23:29 | index expression : pointer type | test.go:23:22:23:29 | index expression : pointer type | -| test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:15:26:36 | type conversion | -| test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:22:26:30 | index expression : pointer type | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:15:26:36 | type conversion | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:26:22:26:30 | implicit dereference : Node | test.go:26:22:26:30 | index expression : pointer type | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:15:26:36 | type conversion | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:22:26:30 | implicit dereference : Node | -| test.go:26:22:26:30 | index expression : pointer type | test.go:26:22:26:30 | index expression : pointer type | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:31:15:31:34 | call to Buffered | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:32:15:32:29 | call to Raw | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:34:15:34:19 | value | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:35:15:35:30 | call to Text | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:36:15:36:44 | type conversion | -| test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:36:22:36:38 | call to Token : Token | -| test.go:36:22:36:38 | call to Token : Token | test.go:36:15:36:44 | type conversion | +| test.go:10:2:10:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | +| test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | +| test.go:16:24:16:35 | selection of Body | test.go:28:22:28:25 | node | +| test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | +| test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | +| test.go:25:45:25:56 | selection of Body | test.go:26:15:26:36 | type conversion | +| test.go:30:33:30:44 | selection of Body | test.go:31:15:31:34 | call to Buffered | +| test.go:30:33:30:44 | selection of Body | test.go:32:15:32:29 | call to Raw | +| test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | +| test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | +| test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | nodes -| test.go:10:2:10:42 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| test.go:10:2:10:42 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:14:15:14:55 | type conversion | semmle.label | type conversion | -| test.go:14:42:14:47 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie | -| test.go:16:24:16:35 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| test.go:16:24:16:35 | selection of Body | semmle.label | selection of Body | | test.go:17:15:17:31 | type conversion | semmle.label | type conversion | -| test.go:17:22:17:25 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:19:36:19:47 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| test.go:19:36:19:47 | selection of Body | semmle.label | selection of Body | | test.go:20:15:20:32 | type conversion | semmle.label | type conversion | -| test.go:20:22:20:26 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:22:33:22:44 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| test.go:22:33:22:44 | selection of Body | semmle.label | selection of Body | | test.go:23:15:23:35 | type conversion | semmle.label | type conversion | -| test.go:23:22:23:29 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:23:22:23:29 | index expression : pointer type | semmle.label | index expression : pointer type | -| test.go:25:45:25:56 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| test.go:25:45:25:56 | selection of Body | semmle.label | selection of Body | | test.go:26:15:26:36 | type conversion | semmle.label | type conversion | -| test.go:26:22:26:30 | implicit dereference : Node | semmle.label | implicit dereference : Node | -| test.go:26:22:26:30 | index expression : pointer type | semmle.label | index expression : pointer type | | test.go:28:22:28:25 | node | semmle.label | node | -| test.go:30:33:30:44 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| test.go:30:33:30:44 | selection of Body | semmle.label | selection of Body | | test.go:31:15:31:34 | call to Buffered | semmle.label | call to Buffered | | test.go:32:15:32:29 | call to Raw | semmle.label | call to Raw | | test.go:34:15:34:19 | value | semmle.label | value | | test.go:35:15:35:30 | call to Text | semmle.label | call to Text | | test.go:36:15:36:44 | type conversion | semmle.label | type conversion | -| test.go:36:22:36:38 | call to Token : Token | semmle.label | call to Token : Token | subpaths #select -| test.go:14:15:14:55 | type conversion | test.go:10:2:10:42 | ... := ...[0] : pointer type | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:10:2:10:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:17:15:17:31 | type conversion | test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:17:15:17:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:20:15:20:32 | type conversion | test.go:19:36:19:47 | selection of Body : ReadCloser | test.go:20:15:20:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:19:36:19:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:23:15:23:35 | type conversion | test.go:22:33:22:44 | selection of Body : ReadCloser | test.go:23:15:23:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:33:22:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:26:15:26:36 | type conversion | test.go:25:45:25:56 | selection of Body : ReadCloser | test.go:26:15:26:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:25:45:25:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:28:22:28:25 | node | test.go:16:24:16:35 | selection of Body : ReadCloser | test.go:28:22:28:25 | node | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:31:15:31:34 | call to Buffered | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:31:15:31:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:32:15:32:29 | call to Raw | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:32:15:32:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:34:15:34:19 | value | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:34:15:34:19 | value | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:35:15:35:30 | call to Text | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:35:15:35:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:36:15:36:44 | type conversion | test.go:30:33:30:44 | selection of Body : ReadCloser | test.go:36:15:36:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:14:15:14:55 | type conversion | test.go:10:2:10:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:10:2:10:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:17:15:17:31 | type conversion | test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:20:15:20:32 | type conversion | test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:19:36:19:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:23:15:23:35 | type conversion | test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:33:22:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:26:15:26:36 | type conversion | test.go:25:45:25:56 | selection of Body | test.go:26:15:26:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:25:45:25:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:28:22:28:25 | node | test.go:16:24:16:35 | selection of Body | test.go:28:22:28:25 | node | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:31:15:31:34 | call to Buffered | test.go:30:33:30:44 | selection of Body | test.go:31:15:31:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:32:15:32:29 | call to Raw | test.go:30:33:30:44 | selection of Body | test.go:32:15:32:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:34:15:34:19 | value | test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:35:15:35:30 | call to Text | test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:36:15:36:44 | type conversion | test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected index f73dd03f976..029366069d2 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected @@ -1,12 +1,12 @@ edges -| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:12:38:12:39 | re | +| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | nodes -| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" : string | semmle.label | "^((www\|beta).)?example.com/" : string | +| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | semmle.label | "^((www\|beta).)?example.com/" | | IncompleteHostnameRegexp.go:12:38:12:39 | re | semmle.label | re | | main.go:39:60:39:79 | "^test2.github.com$" | semmle.label | "^test2.github.com$" | | main.go:44:15:44:39 | `https://www.example.com` | semmle.label | `https://www.example.com` | subpaths #select -| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" : string | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | +| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | | main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | main.go:39:60:39:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:39:60:39:79 | "^test2.github.com$" | the regular expression is used | | main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | main.go:44:15:44:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:44:15:44:39 | `https://www.example.com` | the regular expression is used | diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index acbcbcdeb31..3e26f767b5e 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -1,19 +1,15 @@ edges -| TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:16:29:16:40 | tainted_path | -| TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:20:28:20:69 | call to Join | -| tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:47 | implicit dereference : FileHeader | -| tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:56 | selection of Filename | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | tst.go:17:41:17:47 | implicit dereference : FileHeader | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | tst.go:17:41:17:56 | selection of Filename | +| TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:16:29:16:40 | tainted_path | +| TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:20:28:20:69 | call to Join | +| tst.go:14:2:14:39 | ... := ...[1] | tst.go:17:41:17:56 | selection of Filename | nodes -| TaintedPath.go:13:18:13:22 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| TaintedPath.go:13:18:13:22 | selection of URL | semmle.label | selection of URL | | TaintedPath.go:16:29:16:40 | tainted_path | semmle.label | tainted_path | | TaintedPath.go:20:28:20:69 | call to Join | semmle.label | call to Join | -| tst.go:14:2:14:39 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | -| tst.go:17:41:17:47 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | +| tst.go:14:2:14:39 | ... := ...[1] | semmle.label | ... := ...[1] | | tst.go:17:41:17:56 | selection of Filename | semmle.label | selection of Filename | subpaths #select -| TaintedPath.go:16:29:16:40 | tainted_path | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:16:29:16:40 | tainted_path | This path depends on a $@. | TaintedPath.go:13:18:13:22 | selection of URL | user-provided value | -| TaintedPath.go:20:28:20:69 | call to Join | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:20:28:20:69 | call to Join | This path depends on a $@. | TaintedPath.go:13:18:13:22 | selection of URL | user-provided value | -| tst.go:17:41:17:56 | selection of Filename | tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:56 | selection of Filename | This path depends on a $@. | tst.go:14:2:14:39 | ... := ...[1] | user-provided value | +| TaintedPath.go:16:29:16:40 | tainted_path | TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:16:29:16:40 | tainted_path | This path depends on a $@. | TaintedPath.go:13:18:13:22 | selection of URL | user-provided value | +| TaintedPath.go:20:28:20:69 | call to Join | TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:20:28:20:69 | call to Join | This path depends on a $@. | TaintedPath.go:13:18:13:22 | selection of URL | user-provided value | +| tst.go:17:41:17:56 | selection of Filename | tst.go:14:2:14:39 | ... := ...[1] | tst.go:17:41:17:56 | selection of Filename | This path depends on a $@. | tst.go:14:2:14:39 | ... := ...[1] | user-provided value | diff --git a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.expected b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.expected index f44b118d7d5..da8dc7ed50e 100644 --- a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.expected +++ b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.expected @@ -1,22 +1,22 @@ edges -| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName : string | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | -| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName : string | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | -| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname : string | UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName : string | -| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name : string | UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName : string | +| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | +| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | +| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | +| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | nodes | UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | semmle.label | selection of Linkname | | UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | semmle.label | selection of Name | | UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | semmle.label | selection of Name | -| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName : string | semmle.label | definition of linkName : string | -| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName : string | semmle.label | definition of fileName : string | +| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | semmle.label | definition of linkName | +| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | semmle.label | definition of fileName | | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | semmle.label | linkName | | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | semmle.label | fileName | -| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname : string | semmle.label | selection of Linkname : string | -| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name : string | semmle.label | selection of Name : string | +| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | semmle.label | selection of Linkname | +| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | semmle.label | selection of Name | subpaths #select | UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | symlink creation | | UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | symlink creation | | UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | symlink creation | -| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname : string | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | symlink creation | -| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name : string | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | symlink creation | +| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | symlink creation | +| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | symlink creation | diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected index 35714558cc5..1506632f5c5 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected @@ -1,59 +1,27 @@ edges -| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | -| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:12:24:12:24 | implicit dereference : File | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:14:20:14:20 | p | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:12:24:12:24 | implicit dereference : File | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | ZipSlip.go:14:20:14:20 | p | -| ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | ZipSlip.go:14:20:14:20 | p | -| tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | tarslip.go:16:14:16:34 | call to Dir | -| tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | tarslip.go:16:23:16:28 | implicit dereference : Header | -| tarslip.go:16:23:16:28 | implicit dereference : Header | tarslip.go:16:14:16:34 | call to Dir | -| tarslip.go:16:23:16:28 | implicit dereference : Header | tarslip.go:16:23:16:28 | implicit dereference : Header | -| tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:24:11:24:11 | implicit dereference : File | -| tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | -| tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:29:20:29:23 | path | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:24:11:24:11 | implicit dereference : File | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | -| tst.go:24:11:24:11 | implicit dereference : File | tst.go:29:20:29:23 | path | -| tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | tst.go:29:20:29:23 | path | +| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | +| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | +| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | +| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | +| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | +| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | +| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | +| tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | nodes -| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate : string | semmle.label | definition of candidate : string | +| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | semmle.label | definition of candidate | | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join | -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | -| UnsafeUnzipSymlinkGood.go:76:24:76:29 | implicit dereference : Header | semmle.label | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname : string | semmle.label | selection of Linkname : string | -| UnsafeUnzipSymlinkGood.go:76:70:76:75 | implicit dereference : Header | semmle.label | implicit dereference : Header | -| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name : string | semmle.label | selection of Name : string | -| ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | semmle.label | range statement[1] : pointer type | -| ZipSlip.go:12:24:12:24 | implicit dereference : File | semmle.label | implicit dereference : File | -| ZipSlip.go:12:24:12:24 | implicit read of field FileHeader : FileHeader | semmle.label | implicit read of field FileHeader : FileHeader | +| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | semmle.label | ... := ...[0] | +| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname | +| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name | +| ZipSlip.go:11:2:15:2 | range statement[1] | semmle.label | range statement[1] | | ZipSlip.go:14:20:14:20 | p | semmle.label | p | -| tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| tarslip.go:15:2:15:30 | ... := ...[0] | semmle.label | ... := ...[0] | | tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir | -| tarslip.go:16:23:16:28 | implicit dereference : Header | semmle.label | implicit dereference : Header | -| tst.go:23:2:43:2 | range statement[1] : pointer type | semmle.label | range statement[1] : pointer type | -| tst.go:24:11:24:11 | implicit dereference : File | semmle.label | implicit dereference : File | -| tst.go:24:11:24:11 | implicit read of field FileHeader : FileHeader | semmle.label | implicit read of field FileHeader : FileHeader | +| tst.go:23:2:43:2 | range statement[1] | semmle.label | range statement[1] | | tst.go:29:20:29:23 | path | semmle.label | path | subpaths #select -| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] : pointer type | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation | -| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:11:2:15:2 | range statement[1] : pointer type | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation | -| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] : pointer type | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation | -| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] : pointer type | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation | +| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation | +| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation | +| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation | +| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation | diff --git a/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go b/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go new file mode 100644 index 00000000000..d38d4662542 --- /dev/null +++ b/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go @@ -0,0 +1,12 @@ +package main + +import ( + "net/http" + "os/exec" +) + +func handler2(req *http.Request) { + path := req.URL.Query()["path"][0] + cmd := exec.Command("rsync", path, "/tmp") + cmd.Run() +} diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index 02c56107106..b55f04d6eed 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -1,49 +1,52 @@ edges -| CommandInjection.go:9:13:9:19 | selection of URL : pointer type | CommandInjection.go:10:22:10:28 | cmdName | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:12:31:12:37 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:13:31:13:37 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:14:30:14:36 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:15:35:15:41 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:16:36:16:42 | tainted | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:14:23:14:33 | slice expression | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:80:23:80:29 | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:96:24:96:34 | slice expression | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:101:24:101:34 | slice expression | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:105:30:105:36 | tainted : string | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:148:30:148:36 | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:152:24:152:30 | tainted | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] : string | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | -| SanitizingDoubleDash.go:105:30:105:36 | tainted : string | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] : string | +| ArgumentInjection.go:9:10:9:16 | selection of URL | ArgumentInjection.go:10:31:10:34 | path | +| CommandInjection.go:9:13:9:19 | selection of URL | CommandInjection.go:10:22:10:28 | cmdName | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:12:31:12:37 | tainted | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:13:31:13:37 | tainted | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:14:30:14:36 | tainted | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:15:35:15:41 | tainted | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:16:36:16:42 | tainted | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:14:23:14:33 | slice expression | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:80:23:80:29 | tainted | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:96:24:96:34 | slice expression | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:101:24:101:34 | slice expression | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:105:30:105:36 | tainted | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:148:30:148:36 | tainted | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:152:24:152:30 | tainted | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | +| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | nodes -| CommandInjection.go:9:13:9:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| ArgumentInjection.go:9:10:9:16 | selection of URL | semmle.label | selection of URL | +| ArgumentInjection.go:10:31:10:34 | path | semmle.label | path | +| CommandInjection.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | CommandInjection.go:10:22:10:28 | cmdName | semmle.label | cmdName | -| GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| GitSubcommands.go:10:13:10:19 | selection of URL | semmle.label | selection of URL | | GitSubcommands.go:12:31:12:37 | tainted | semmle.label | tainted | | GitSubcommands.go:13:31:13:37 | tainted | semmle.label | tainted | | GitSubcommands.go:14:30:14:36 | tainted | semmle.label | tainted | | GitSubcommands.go:15:35:15:41 | tainted | semmle.label | tainted | | GitSubcommands.go:16:36:16:42 | tainted | semmle.label | tainted | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:14:23:14:33 | slice expression | semmle.label | slice expression | | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:80:23:80:29 | tainted | semmle.label | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression | | SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] : string | semmle.label | slice literal [array] : string | -| SanitizingDoubleDash.go:105:30:105:36 | tainted : string | semmle.label | tainted : string | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] | +| SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | semmle.label | arrayLit | @@ -55,25 +58,26 @@ nodes | SanitizingDoubleDash.go:152:24:152:30 | tainted | semmle.label | tainted | subpaths #select -| CommandInjection.go:10:22:10:28 | cmdName | CommandInjection.go:9:13:9:19 | selection of URL : pointer type | CommandInjection.go:10:22:10:28 | cmdName | This command depends on a $@. | CommandInjection.go:9:13:9:19 | selection of URL | user-provided value | -| GitSubcommands.go:12:31:12:37 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:12:31:12:37 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | -| GitSubcommands.go:13:31:13:37 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:13:31:13:37 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | -| GitSubcommands.go:14:30:14:36 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:14:30:14:36 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | -| GitSubcommands.go:15:35:15:41 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:15:35:15:41 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | -| GitSubcommands.go:16:36:16:42 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL : pointer type | GitSubcommands.go:16:36:16:42 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:14:23:14:33 | slice expression | SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:14:23:14:33 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:40:23:40:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:54:23:54:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:70:23:70:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:80:23:80:29 | tainted | SanitizingDoubleDash.go:9:13:9:19 | selection of URL : pointer type | SanitizingDoubleDash.go:80:23:80:29 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:96:24:96:34 | slice expression | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:96:24:96:34 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:101:24:101:34 | slice expression | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:101:24:101:34 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:106:24:106:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:112:24:112:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:118:24:118:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:124:24:124:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:130:24:130:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:137:24:137:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:144:24:144:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:148:30:148:36 | tainted | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:148:30:148:36 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | -| SanitizingDoubleDash.go:152:24:152:30 | tainted | SanitizingDoubleDash.go:92:13:92:19 | selection of URL : pointer type | SanitizingDoubleDash.go:152:24:152:30 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| ArgumentInjection.go:10:31:10:34 | path | ArgumentInjection.go:9:10:9:16 | selection of URL | ArgumentInjection.go:10:31:10:34 | path | This command depends on a $@. | ArgumentInjection.go:9:10:9:16 | selection of URL | user-provided value | +| CommandInjection.go:10:22:10:28 | cmdName | CommandInjection.go:9:13:9:19 | selection of URL | CommandInjection.go:10:22:10:28 | cmdName | This command depends on a $@. | CommandInjection.go:9:13:9:19 | selection of URL | user-provided value | +| GitSubcommands.go:12:31:12:37 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:12:31:12:37 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | +| GitSubcommands.go:13:31:13:37 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:13:31:13:37 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | +| GitSubcommands.go:14:30:14:36 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:14:30:14:36 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | +| GitSubcommands.go:15:35:15:41 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:15:35:15:41 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | +| GitSubcommands.go:16:36:16:42 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:16:36:16:42 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:14:23:14:33 | slice expression | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:14:23:14:33 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:40:23:40:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:54:23:54:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:70:23:70:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:80:23:80:29 | tainted | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:80:23:80:29 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:96:24:96:34 | slice expression | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:96:24:96:34 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:101:24:101:34 | slice expression | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:101:24:101:34 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:106:24:106:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:112:24:112:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:118:24:118:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:124:24:124:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:130:24:130:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:137:24:137:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:144:24:144:31 | arrayLit | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:148:30:148:36 | tainted | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:148:30:148:36 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | +| SanitizingDoubleDash.go:152:24:152:30 | tainted | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:152:24:152:30 | tainted | This command depends on a $@. | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | user-provided value | diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected index a01ffb68838..ea667480966 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected @@ -1,8 +1,8 @@ edges -| StoredCommand.go:11:2:11:27 | ... := ...[0] : pointer type | StoredCommand.go:14:22:14:28 | cmdName | +| StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:14:22:14:28 | cmdName | nodes -| StoredCommand.go:11:2:11:27 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| StoredCommand.go:11:2:11:27 | ... := ...[0] | semmle.label | ... := ...[0] | | StoredCommand.go:14:22:14:28 | cmdName | semmle.label | cmdName | subpaths #select -| StoredCommand.go:14:22:14:28 | cmdName | StoredCommand.go:11:2:11:27 | ... := ...[0] : pointer type | StoredCommand.go:14:22:14:28 | cmdName | This command depends on a $@. | StoredCommand.go:11:2:11:27 | ... := ...[0] | stored value | +| StoredCommand.go:14:22:14:28 | cmdName | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:14:22:14:28 | cmdName | This command depends on a $@. | StoredCommand.go:11:2:11:27 | ... := ...[0] | stored value | diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index a71e27e63ac..428f3e9edd3 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1,91 +1,87 @@ edges -| ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:44:14:51 | username | -| contenttype.go:11:11:11:16 | selection of Form : Values | contenttype.go:17:11:17:22 | type conversion | -| contenttype.go:49:11:49:16 | selection of Form : Values | contenttype.go:53:34:53:37 | data | -| contenttype.go:63:10:63:28 | call to FormValue : string | contenttype.go:64:52:64:55 | data | -| contenttype.go:73:10:73:28 | call to FormValue : string | contenttype.go:79:11:79:14 | data | -| contenttype.go:88:10:88:28 | call to FormValue : string | contenttype.go:91:4:91:7 | data | -| contenttype.go:113:10:113:28 | call to FormValue : string | contenttype.go:114:50:114:53 | data | -| reflectedxsstest.go:27:2:27:38 | ... := ...[0] : pointer type | reflectedxsstest.go:28:10:28:57 | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[0] : File | reflectedxsstest.go:33:10:33:57 | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | -| reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:44:10:44:55 | type conversion | -| reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:45:10:45:18 | byteSlice | -| reflectedxsstest.go:51:14:51:18 | selection of URL : pointer type | reflectedxsstest.go:54:11:54:21 | type conversion | -| tst.go:14:15:14:20 | selection of Form : Values | tst.go:18:12:18:39 | type conversion | -| tst.go:48:14:48:19 | selection of Form : Values | tst.go:53:12:53:26 | type conversion | -| websocketXss.go:30:7:30:10 | definition of xnet : slice type | websocketXss.go:32:24:32:27 | xnet | -| websocketXss.go:34:3:34:7 | definition of xnet2 : slice type | websocketXss.go:36:24:36:28 | xnet2 | -| websocketXss.go:40:3:40:40 | ... := ...[1] : slice type | websocketXss.go:41:24:41:29 | nhooyr | -| websocketXss.go:46:7:46:16 | definition of gorillaMsg : slice type | websocketXss.go:48:24:48:33 | gorillaMsg | -| websocketXss.go:50:3:50:10 | definition of gorilla2 : slice type | websocketXss.go:52:24:52:31 | gorilla2 | -| websocketXss.go:54:3:54:38 | ... := ...[1] : slice type | websocketXss.go:55:24:55:31 | gorilla3 | +| ReflectedXss.go:11:15:11:20 | selection of Form | ReflectedXss.go:14:44:14:51 | username | +| contenttype.go:11:11:11:16 | selection of Form | contenttype.go:17:11:17:22 | type conversion | +| contenttype.go:49:11:49:16 | selection of Form | contenttype.go:53:34:53:37 | data | +| contenttype.go:63:10:63:28 | call to FormValue | contenttype.go:64:52:64:55 | data | +| contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | +| contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | +| contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | +| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | +| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | +| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | +| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | +| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:45:10:45:18 | byteSlice | +| reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:54:11:54:21 | type conversion | +| tst.go:14:15:14:20 | selection of Form | tst.go:18:12:18:39 | type conversion | +| tst.go:48:14:48:19 | selection of Form | tst.go:53:12:53:26 | type conversion | +| websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | +| websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | +| websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | +| websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | +| websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | +| websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | nodes -| ReflectedXss.go:11:15:11:20 | selection of Form : Values | semmle.label | selection of Form : Values | +| ReflectedXss.go:11:15:11:20 | selection of Form | semmle.label | selection of Form | | ReflectedXss.go:14:44:14:51 | username | semmle.label | username | -| contenttype.go:11:11:11:16 | selection of Form : Values | semmle.label | selection of Form : Values | +| contenttype.go:11:11:11:16 | selection of Form | semmle.label | selection of Form | | contenttype.go:17:11:17:22 | type conversion | semmle.label | type conversion | -| contenttype.go:49:11:49:16 | selection of Form : Values | semmle.label | selection of Form : Values | +| contenttype.go:49:11:49:16 | selection of Form | semmle.label | selection of Form | | contenttype.go:53:34:53:37 | data | semmle.label | data | -| contenttype.go:63:10:63:28 | call to FormValue : string | semmle.label | call to FormValue : string | +| contenttype.go:63:10:63:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:64:52:64:55 | data | semmle.label | data | -| contenttype.go:73:10:73:28 | call to FormValue : string | semmle.label | call to FormValue : string | +| contenttype.go:73:10:73:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:79:11:79:14 | data | semmle.label | data | -| contenttype.go:88:10:88:28 | call to FormValue : string | semmle.label | call to FormValue : string | +| contenttype.go:88:10:88:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:91:4:91:7 | data | semmle.label | data | -| contenttype.go:113:10:113:28 | call to FormValue : string | semmle.label | call to FormValue : string | +| contenttype.go:113:10:113:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:114:50:114:53 | data | semmle.label | data | -| reflectedxsstest.go:27:2:27:38 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:28:10:28:57 | type conversion | semmle.label | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[0] : File | semmle.label | ... := ...[0] : File | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | semmle.label | ... := ...[1] : pointer type | +| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:34:10:34:62 | type conversion | semmle.label | type conversion | -| reflectedxsstest.go:34:46:34:51 | implicit dereference : FileHeader | semmle.label | implicit dereference : FileHeader | -| reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:44:10:44:55 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:45:10:45:18 | byteSlice | semmle.label | byteSlice | -| reflectedxsstest.go:51:14:51:18 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| reflectedxsstest.go:51:14:51:18 | selection of URL | semmle.label | selection of URL | | reflectedxsstest.go:54:11:54:21 | type conversion | semmle.label | type conversion | -| tst.go:14:15:14:20 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:14:15:14:20 | selection of Form | semmle.label | selection of Form | | tst.go:18:12:18:39 | type conversion | semmle.label | type conversion | -| tst.go:48:14:48:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:48:14:48:19 | selection of Form | semmle.label | selection of Form | | tst.go:53:12:53:26 | type conversion | semmle.label | type conversion | -| websocketXss.go:30:7:30:10 | definition of xnet : slice type | semmle.label | definition of xnet : slice type | +| websocketXss.go:30:7:30:10 | definition of xnet | semmle.label | definition of xnet | | websocketXss.go:32:24:32:27 | xnet | semmle.label | xnet | -| websocketXss.go:34:3:34:7 | definition of xnet2 : slice type | semmle.label | definition of xnet2 : slice type | +| websocketXss.go:34:3:34:7 | definition of xnet2 | semmle.label | definition of xnet2 | | websocketXss.go:36:24:36:28 | xnet2 | semmle.label | xnet2 | -| websocketXss.go:40:3:40:40 | ... := ...[1] : slice type | semmle.label | ... := ...[1] : slice type | +| websocketXss.go:40:3:40:40 | ... := ...[1] | semmle.label | ... := ...[1] | | websocketXss.go:41:24:41:29 | nhooyr | semmle.label | nhooyr | -| websocketXss.go:46:7:46:16 | definition of gorillaMsg : slice type | semmle.label | definition of gorillaMsg : slice type | +| websocketXss.go:46:7:46:16 | definition of gorillaMsg | semmle.label | definition of gorillaMsg | | websocketXss.go:48:24:48:33 | gorillaMsg | semmle.label | gorillaMsg | -| websocketXss.go:50:3:50:10 | definition of gorilla2 : slice type | semmle.label | definition of gorilla2 : slice type | +| websocketXss.go:50:3:50:10 | definition of gorilla2 | semmle.label | definition of gorilla2 | | websocketXss.go:52:24:52:31 | gorilla2 | semmle.label | gorilla2 | -| websocketXss.go:54:3:54:38 | ... := ...[1] : slice type | semmle.label | ... := ...[1] : slice type | +| websocketXss.go:54:3:54:38 | ... := ...[1] | semmle.label | ... := ...[1] | | websocketXss.go:55:24:55:31 | gorilla3 | semmle.label | gorilla3 | subpaths #select -| ReflectedXss.go:14:44:14:51 | username | ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:44:14:51 | username | Cross-site scripting vulnerability due to $@. | ReflectedXss.go:11:15:11:20 | selection of Form | user-provided value | ReflectedXss.go:0:0:0:0 | ReflectedXss.go | | -| contenttype.go:17:11:17:22 | type conversion | contenttype.go:11:11:11:16 | selection of Form : Values | contenttype.go:17:11:17:22 | type conversion | Cross-site scripting vulnerability due to $@. | contenttype.go:11:11:11:16 | selection of Form | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| contenttype.go:53:34:53:37 | data | contenttype.go:49:11:49:16 | selection of Form : Values | contenttype.go:53:34:53:37 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:49:11:49:16 | selection of Form | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| contenttype.go:64:52:64:55 | data | contenttype.go:63:10:63:28 | call to FormValue : string | contenttype.go:64:52:64:55 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:63:10:63:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| contenttype.go:79:11:79:14 | data | contenttype.go:73:10:73:28 | call to FormValue : string | contenttype.go:79:11:79:14 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:73:10:73:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| contenttype.go:91:4:91:7 | data | contenttype.go:88:10:88:28 | call to FormValue : string | contenttype.go:91:4:91:7 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:88:10:88:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| contenttype.go:114:50:114:53 | data | contenttype.go:113:10:113:28 | call to FormValue : string | contenttype.go:114:50:114:53 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:113:10:113:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| reflectedxsstest.go:28:10:28:57 | type conversion | reflectedxsstest.go:27:2:27:38 | ... := ...[0] : pointer type | reflectedxsstest.go:28:10:28:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[0] : File | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[1] : pointer type | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:44:10:44:55 | type conversion | reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:44:10:44:55 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:45:10:45:18 | byteSlice | reflectedxsstest.go:38:2:38:35 | ... := ...[0] : pointer type | reflectedxsstest.go:45:10:45:18 | byteSlice | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| reflectedxsstest.go:54:11:54:21 | type conversion | reflectedxsstest.go:51:14:51:18 | selection of URL : pointer type | reflectedxsstest.go:54:11:54:21 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:51:14:51:18 | selection of URL | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | -| tst.go:18:12:18:39 | type conversion | tst.go:14:15:14:20 | selection of Form : Values | tst.go:18:12:18:39 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:14:15:14:20 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | -| tst.go:53:12:53:26 | type conversion | tst.go:48:14:48:19 | selection of Form : Values | tst.go:53:12:53:26 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:48:14:48:19 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | -| websocketXss.go:32:24:32:27 | xnet | websocketXss.go:30:7:30:10 | definition of xnet : slice type | websocketXss.go:32:24:32:27 | xnet | Cross-site scripting vulnerability due to $@. | websocketXss.go:30:7:30:10 | definition of xnet | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:36:24:36:28 | xnet2 | websocketXss.go:34:3:34:7 | definition of xnet2 : slice type | websocketXss.go:36:24:36:28 | xnet2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:34:3:34:7 | definition of xnet2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:41:24:41:29 | nhooyr | websocketXss.go:40:3:40:40 | ... := ...[1] : slice type | websocketXss.go:41:24:41:29 | nhooyr | Cross-site scripting vulnerability due to $@. | websocketXss.go:40:3:40:40 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:48:24:48:33 | gorillaMsg | websocketXss.go:46:7:46:16 | definition of gorillaMsg : slice type | websocketXss.go:48:24:48:33 | gorillaMsg | Cross-site scripting vulnerability due to $@. | websocketXss.go:46:7:46:16 | definition of gorillaMsg | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:52:24:52:31 | gorilla2 | websocketXss.go:50:3:50:10 | definition of gorilla2 : slice type | websocketXss.go:52:24:52:31 | gorilla2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:50:3:50:10 | definition of gorilla2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:55:24:55:31 | gorilla3 | websocketXss.go:54:3:54:38 | ... := ...[1] : slice type | websocketXss.go:55:24:55:31 | gorilla3 | Cross-site scripting vulnerability due to $@. | websocketXss.go:54:3:54:38 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| ReflectedXss.go:14:44:14:51 | username | ReflectedXss.go:11:15:11:20 | selection of Form | ReflectedXss.go:14:44:14:51 | username | Cross-site scripting vulnerability due to $@. | ReflectedXss.go:11:15:11:20 | selection of Form | user-provided value | ReflectedXss.go:0:0:0:0 | ReflectedXss.go | | +| contenttype.go:17:11:17:22 | type conversion | contenttype.go:11:11:11:16 | selection of Form | contenttype.go:17:11:17:22 | type conversion | Cross-site scripting vulnerability due to $@. | contenttype.go:11:11:11:16 | selection of Form | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| contenttype.go:53:34:53:37 | data | contenttype.go:49:11:49:16 | selection of Form | contenttype.go:53:34:53:37 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:49:11:49:16 | selection of Form | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| contenttype.go:64:52:64:55 | data | contenttype.go:63:10:63:28 | call to FormValue | contenttype.go:64:52:64:55 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:63:10:63:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| contenttype.go:79:11:79:14 | data | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:73:10:73:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| contenttype.go:91:4:91:7 | data | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:88:10:88:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| contenttype.go:114:50:114:53 | data | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:113:10:113:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | +| reflectedxsstest.go:28:10:28:57 | type conversion | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:44:10:44:55 | type conversion | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:45:10:45:18 | byteSlice | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:45:10:45:18 | byteSlice | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| reflectedxsstest.go:54:11:54:21 | type conversion | reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:54:11:54:21 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:51:14:51:18 | selection of URL | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | +| tst.go:18:12:18:39 | type conversion | tst.go:14:15:14:20 | selection of Form | tst.go:18:12:18:39 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:14:15:14:20 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | +| tst.go:53:12:53:26 | type conversion | tst.go:48:14:48:19 | selection of Form | tst.go:53:12:53:26 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:48:14:48:19 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | +| websocketXss.go:32:24:32:27 | xnet | websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | Cross-site scripting vulnerability due to $@. | websocketXss.go:30:7:30:10 | definition of xnet | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:36:24:36:28 | xnet2 | websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:34:3:34:7 | definition of xnet2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:41:24:41:29 | nhooyr | websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | Cross-site scripting vulnerability due to $@. | websocketXss.go:40:3:40:40 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:48:24:48:33 | gorillaMsg | websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | Cross-site scripting vulnerability due to $@. | websocketXss.go:46:7:46:16 | definition of gorillaMsg | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:52:24:52:31 | gorilla2 | websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:50:3:50:10 | definition of gorilla2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:55:24:55:31 | gorilla3 | websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | Cross-site scripting vulnerability due to $@. | websocketXss.go:54:3:54:38 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | diff --git a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected index b93e7c74201..1e513a5d4a9 100644 --- a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -1,16 +1,16 @@ edges -| StoredXss.go:13:21:13:31 | call to Name : string | StoredXss.go:13:21:13:36 | ...+... | -| stored.go:18:3:18:28 | ... := ...[0] : pointer type | stored.go:30:22:30:25 | name | -| stored.go:59:30:59:33 | definition of path : string | stored.go:61:22:61:25 | path | +| StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | +| stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | +| stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | nodes -| StoredXss.go:13:21:13:31 | call to Name : string | semmle.label | call to Name : string | +| StoredXss.go:13:21:13:31 | call to Name | semmle.label | call to Name | | StoredXss.go:13:21:13:36 | ...+... | semmle.label | ...+... | -| stored.go:18:3:18:28 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type | +| stored.go:18:3:18:28 | ... := ...[0] | semmle.label | ... := ...[0] | | stored.go:30:22:30:25 | name | semmle.label | name | -| stored.go:59:30:59:33 | definition of path : string | semmle.label | definition of path : string | +| stored.go:59:30:59:33 | definition of path | semmle.label | definition of path | | stored.go:61:22:61:25 | path | semmle.label | path | subpaths #select -| StoredXss.go:13:21:13:36 | ...+... | StoredXss.go:13:21:13:31 | call to Name : string | StoredXss.go:13:21:13:36 | ...+... | Stored cross-site scripting vulnerability due to $@. | StoredXss.go:13:21:13:31 | call to Name | stored value | -| stored.go:30:22:30:25 | name | stored.go:18:3:18:28 | ... := ...[0] : pointer type | stored.go:30:22:30:25 | name | Stored cross-site scripting vulnerability due to $@. | stored.go:18:3:18:28 | ... := ...[0] | stored value | -| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path : string | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value | +| StoredXss.go:13:21:13:36 | ...+... | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | Stored cross-site scripting vulnerability due to $@. | StoredXss.go:13:21:13:31 | call to Name | stored value | +| stored.go:30:22:30:25 | name | stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | Stored cross-site scripting vulnerability due to $@. | stored.go:18:3:18:28 | ... := ...[0] | stored value | +| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value | diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 521824433a2..7f9f8a8f19f 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,112 +1,112 @@ edges -| SqlInjection.go:11:3:11:9 | selection of URL : pointer type | SqlInjection.go:12:11:12:11 | q | -| issue48.go:17:25:17:32 | selection of Body : ReadCloser | issue48.go:22:11:22:12 | q3 | -| issue48.go:27:26:27:33 | selection of Body : ReadCloser | issue48.go:32:11:32:12 | q4 | -| issue48.go:37:17:37:50 | type conversion : string | issue48.go:41:11:41:12 | q5 | -| issue48.go:37:24:37:30 | selection of URL : pointer type | issue48.go:37:17:37:50 | type conversion : string | -| main.go:10:11:10:16 | selection of Form : Values | main.go:10:11:10:28 | index expression | -| main.go:14:63:14:67 | selection of URL : pointer type | main.go:14:11:14:84 | call to Sprintf | -| main.go:15:63:15:70 | selection of Header : Header | main.go:15:11:15:85 | call to Sprintf | -| main.go:27:17:30:2 | &... [pointer, Category] : slice type | main.go:33:3:33:13 | RequestData [pointer, Category] : slice type | -| main.go:27:18:30:2 | struct literal [Category] : slice type | main.go:27:17:30:2 | &... [pointer, Category] : slice type | -| main.go:29:13:29:19 | selection of URL : pointer type | main.go:29:13:29:39 | index expression : slice type | -| main.go:29:13:29:39 | index expression : slice type | main.go:27:18:30:2 | struct literal [Category] : slice type | -| main.go:33:3:33:13 | RequestData [pointer, Category] : slice type | main.go:33:3:33:13 | implicit dereference [Category] : slice type | -| main.go:33:3:33:13 | implicit dereference [Category] : slice type | main.go:33:3:33:22 | selection of Category : slice type | -| main.go:33:3:33:22 | selection of Category : slice type | main.go:34:11:34:11 | q | -| main.go:38:2:38:12 | definition of RequestData [pointer, Category] : slice type | main.go:39:2:39:12 | RequestData [pointer, Category] : slice type | -| main.go:38:2:38:12 | definition of RequestData [pointer, Category] : slice type | main.go:42:3:42:13 | RequestData [pointer, Category] : slice type | -| main.go:39:2:39:12 | RequestData [pointer, Category] : slice type | main.go:39:2:39:12 | implicit dereference [Category] : slice type | -| main.go:39:2:39:12 | implicit dereference [Category] : slice type | main.go:38:2:38:12 | definition of RequestData [pointer, Category] : slice type | -| main.go:39:25:39:31 | selection of URL : pointer type | main.go:39:25:39:51 | index expression : slice type | -| main.go:39:25:39:51 | index expression : slice type | main.go:39:2:39:12 | implicit dereference [Category] : slice type | -| main.go:42:3:42:13 | RequestData [pointer, Category] : slice type | main.go:42:3:42:13 | implicit dereference [Category] : slice type | -| main.go:42:3:42:13 | implicit dereference [Category] : slice type | main.go:42:3:42:22 | selection of Category : slice type | -| main.go:42:3:42:22 | selection of Category : slice type | main.go:43:11:43:11 | q | -| main.go:47:2:47:12 | definition of RequestData [pointer, Category] : slice type | main.go:48:4:48:14 | RequestData [pointer, Category] : slice type | -| main.go:47:2:47:12 | definition of RequestData [pointer, Category] : slice type | main.go:51:3:51:13 | RequestData [pointer, Category] : slice type | -| main.go:48:3:48:14 | star expression [Category] : slice type | main.go:47:2:47:12 | definition of RequestData [pointer, Category] : slice type | -| main.go:48:4:48:14 | RequestData [pointer, Category] : slice type | main.go:48:3:48:14 | star expression [Category] : slice type | -| main.go:48:28:48:34 | selection of URL : pointer type | main.go:48:28:48:54 | index expression : slice type | -| main.go:48:28:48:54 | index expression : slice type | main.go:48:3:48:14 | star expression [Category] : slice type | -| main.go:51:3:51:13 | RequestData [pointer, Category] : slice type | main.go:51:3:51:13 | implicit dereference [Category] : slice type | -| main.go:51:3:51:13 | implicit dereference [Category] : slice type | main.go:51:3:51:22 | selection of Category : slice type | -| main.go:51:3:51:22 | selection of Category : slice type | main.go:52:11:52:11 | q | -| main.go:56:2:56:12 | definition of RequestData [pointer, Category] : slice type | main.go:57:4:57:14 | RequestData [pointer, Category] : slice type | -| main.go:56:2:56:12 | definition of RequestData [pointer, Category] : slice type | main.go:60:5:60:15 | RequestData [pointer, Category] : slice type | -| main.go:57:3:57:14 | star expression [Category] : slice type | main.go:56:2:56:12 | definition of RequestData [pointer, Category] : slice type | -| main.go:57:4:57:14 | RequestData [pointer, Category] : slice type | main.go:57:3:57:14 | star expression [Category] : slice type | -| main.go:57:28:57:34 | selection of URL : pointer type | main.go:57:28:57:54 | index expression : slice type | -| main.go:57:28:57:54 | index expression : slice type | main.go:57:3:57:14 | star expression [Category] : slice type | -| main.go:60:3:60:25 | selection of Category : slice type | main.go:61:11:61:11 | q | -| main.go:60:4:60:15 | star expression [Category] : slice type | main.go:60:3:60:25 | selection of Category : slice type | -| main.go:60:5:60:15 | RequestData [pointer, Category] : slice type | main.go:60:4:60:15 | star expression [Category] : slice type | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:57:22:57:29 | pipeline | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:61:27:61:32 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:63:23:63:28 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:64:22:64:27 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:66:32:66:37 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:69:17:69:22 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:70:20:70:25 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:71:29:71:34 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:72:30:72:35 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:73:29:73:34 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:78:23:78:28 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:79:23:79:28 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:80:22:80:27 | filter | -| mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:81:18:81:25 | pipeline | +| SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:12:11:12:11 | q | +| issue48.go:17:25:17:32 | selection of Body | issue48.go:22:11:22:12 | q3 | +| issue48.go:27:26:27:33 | selection of Body | issue48.go:32:11:32:12 | q4 | +| issue48.go:37:17:37:50 | type conversion | issue48.go:41:11:41:12 | q5 | +| issue48.go:37:24:37:30 | selection of URL | issue48.go:37:17:37:50 | type conversion | +| main.go:10:11:10:16 | selection of Form | main.go:10:11:10:28 | index expression | +| main.go:14:63:14:67 | selection of URL | main.go:14:11:14:84 | call to Sprintf | +| main.go:15:63:15:70 | selection of Header | main.go:15:11:15:85 | call to Sprintf | +| main.go:27:17:30:2 | &... [pointer, Category] | main.go:33:3:33:13 | RequestData [pointer, Category] | +| main.go:27:18:30:2 | struct literal [Category] | main.go:27:17:30:2 | &... [pointer, Category] | +| main.go:29:13:29:19 | selection of URL | main.go:29:13:29:39 | index expression | +| main.go:29:13:29:39 | index expression | main.go:27:18:30:2 | struct literal [Category] | +| main.go:33:3:33:13 | RequestData [pointer, Category] | main.go:33:3:33:13 | implicit dereference [Category] | +| main.go:33:3:33:13 | implicit dereference [Category] | main.go:33:3:33:22 | selection of Category | +| main.go:33:3:33:22 | selection of Category | main.go:34:11:34:11 | q | +| main.go:38:2:38:12 | definition of RequestData [pointer, Category] | main.go:39:2:39:12 | RequestData [pointer, Category] | +| main.go:38:2:38:12 | definition of RequestData [pointer, Category] | main.go:42:3:42:13 | RequestData [pointer, Category] | +| main.go:39:2:39:12 | RequestData [pointer, Category] | main.go:39:2:39:12 | implicit dereference [Category] | +| main.go:39:2:39:12 | implicit dereference [Category] | main.go:38:2:38:12 | definition of RequestData [pointer, Category] | +| main.go:39:25:39:31 | selection of URL | main.go:39:25:39:51 | index expression | +| main.go:39:25:39:51 | index expression | main.go:39:2:39:12 | implicit dereference [Category] | +| main.go:42:3:42:13 | RequestData [pointer, Category] | main.go:42:3:42:13 | implicit dereference [Category] | +| main.go:42:3:42:13 | implicit dereference [Category] | main.go:42:3:42:22 | selection of Category | +| main.go:42:3:42:22 | selection of Category | main.go:43:11:43:11 | q | +| main.go:47:2:47:12 | definition of RequestData [pointer, Category] | main.go:48:4:48:14 | RequestData [pointer, Category] | +| main.go:47:2:47:12 | definition of RequestData [pointer, Category] | main.go:51:3:51:13 | RequestData [pointer, Category] | +| main.go:48:3:48:14 | star expression [Category] | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | +| main.go:48:4:48:14 | RequestData [pointer, Category] | main.go:48:3:48:14 | star expression [Category] | +| main.go:48:28:48:34 | selection of URL | main.go:48:28:48:54 | index expression | +| main.go:48:28:48:54 | index expression | main.go:48:3:48:14 | star expression [Category] | +| main.go:51:3:51:13 | RequestData [pointer, Category] | main.go:51:3:51:13 | implicit dereference [Category] | +| main.go:51:3:51:13 | implicit dereference [Category] | main.go:51:3:51:22 | selection of Category | +| main.go:51:3:51:22 | selection of Category | main.go:52:11:52:11 | q | +| main.go:56:2:56:12 | definition of RequestData [pointer, Category] | main.go:57:4:57:14 | RequestData [pointer, Category] | +| main.go:56:2:56:12 | definition of RequestData [pointer, Category] | main.go:60:5:60:15 | RequestData [pointer, Category] | +| main.go:57:3:57:14 | star expression [Category] | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | +| main.go:57:4:57:14 | RequestData [pointer, Category] | main.go:57:3:57:14 | star expression [Category] | +| main.go:57:28:57:34 | selection of URL | main.go:57:28:57:54 | index expression | +| main.go:57:28:57:54 | index expression | main.go:57:3:57:14 | star expression [Category] | +| main.go:60:3:60:25 | selection of Category | main.go:61:11:61:11 | q | +| main.go:60:4:60:15 | star expression [Category] | main.go:60:3:60:25 | selection of Category | +| main.go:60:5:60:15 | RequestData [pointer, Category] | main.go:60:4:60:15 | star expression [Category] | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:57:22:57:29 | pipeline | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:61:27:61:32 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:63:23:63:28 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:64:22:64:27 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:66:32:66:37 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:69:17:69:22 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:70:20:70:25 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:71:29:71:34 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:72:30:72:35 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:73:29:73:34 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:78:23:78:28 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:79:23:79:28 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:80:22:80:27 | filter | +| mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | nodes -| SqlInjection.go:11:3:11:9 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| SqlInjection.go:11:3:11:9 | selection of URL | semmle.label | selection of URL | | SqlInjection.go:12:11:12:11 | q | semmle.label | q | -| issue48.go:17:25:17:32 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body | | issue48.go:22:11:22:12 | q3 | semmle.label | q3 | -| issue48.go:27:26:27:33 | selection of Body : ReadCloser | semmle.label | selection of Body : ReadCloser | +| issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body | | issue48.go:32:11:32:12 | q4 | semmle.label | q4 | -| issue48.go:37:17:37:50 | type conversion : string | semmle.label | type conversion : string | -| issue48.go:37:24:37:30 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| issue48.go:37:17:37:50 | type conversion | semmle.label | type conversion | +| issue48.go:37:24:37:30 | selection of URL | semmle.label | selection of URL | | issue48.go:41:11:41:12 | q5 | semmle.label | q5 | -| main.go:10:11:10:16 | selection of Form : Values | semmle.label | selection of Form : Values | +| main.go:10:11:10:16 | selection of Form | semmle.label | selection of Form | | main.go:10:11:10:28 | index expression | semmle.label | index expression | | main.go:14:11:14:84 | call to Sprintf | semmle.label | call to Sprintf | -| main.go:14:63:14:67 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| main.go:14:63:14:67 | selection of URL | semmle.label | selection of URL | | main.go:15:11:15:85 | call to Sprintf | semmle.label | call to Sprintf | -| main.go:15:63:15:70 | selection of Header : Header | semmle.label | selection of Header : Header | -| main.go:27:17:30:2 | &... [pointer, Category] : slice type | semmle.label | &... [pointer, Category] : slice type | -| main.go:27:18:30:2 | struct literal [Category] : slice type | semmle.label | struct literal [Category] : slice type | -| main.go:29:13:29:19 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| main.go:29:13:29:39 | index expression : slice type | semmle.label | index expression : slice type | -| main.go:33:3:33:13 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:33:3:33:13 | implicit dereference [Category] : slice type | semmle.label | implicit dereference [Category] : slice type | -| main.go:33:3:33:22 | selection of Category : slice type | semmle.label | selection of Category : slice type | +| main.go:15:63:15:70 | selection of Header | semmle.label | selection of Header | +| main.go:27:17:30:2 | &... [pointer, Category] | semmle.label | &... [pointer, Category] | +| main.go:27:18:30:2 | struct literal [Category] | semmle.label | struct literal [Category] | +| main.go:29:13:29:19 | selection of URL | semmle.label | selection of URL | +| main.go:29:13:29:39 | index expression | semmle.label | index expression | +| main.go:33:3:33:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:33:3:33:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | +| main.go:33:3:33:22 | selection of Category | semmle.label | selection of Category | | main.go:34:11:34:11 | q | semmle.label | q | -| main.go:38:2:38:12 | definition of RequestData [pointer, Category] : slice type | semmle.label | definition of RequestData [pointer, Category] : slice type | -| main.go:39:2:39:12 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:39:2:39:12 | implicit dereference [Category] : slice type | semmle.label | implicit dereference [Category] : slice type | -| main.go:39:25:39:31 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| main.go:39:25:39:51 | index expression : slice type | semmle.label | index expression : slice type | -| main.go:42:3:42:13 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:42:3:42:13 | implicit dereference [Category] : slice type | semmle.label | implicit dereference [Category] : slice type | -| main.go:42:3:42:22 | selection of Category : slice type | semmle.label | selection of Category : slice type | +| main.go:38:2:38:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | +| main.go:39:2:39:12 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:39:2:39:12 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | +| main.go:39:25:39:31 | selection of URL | semmle.label | selection of URL | +| main.go:39:25:39:51 | index expression | semmle.label | index expression | +| main.go:42:3:42:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:42:3:42:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | +| main.go:42:3:42:22 | selection of Category | semmle.label | selection of Category | | main.go:43:11:43:11 | q | semmle.label | q | -| main.go:47:2:47:12 | definition of RequestData [pointer, Category] : slice type | semmle.label | definition of RequestData [pointer, Category] : slice type | -| main.go:48:3:48:14 | star expression [Category] : slice type | semmle.label | star expression [Category] : slice type | -| main.go:48:4:48:14 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:48:28:48:34 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| main.go:48:28:48:54 | index expression : slice type | semmle.label | index expression : slice type | -| main.go:51:3:51:13 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:51:3:51:13 | implicit dereference [Category] : slice type | semmle.label | implicit dereference [Category] : slice type | -| main.go:51:3:51:22 | selection of Category : slice type | semmle.label | selection of Category : slice type | +| main.go:47:2:47:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | +| main.go:48:3:48:14 | star expression [Category] | semmle.label | star expression [Category] | +| main.go:48:4:48:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:48:28:48:34 | selection of URL | semmle.label | selection of URL | +| main.go:48:28:48:54 | index expression | semmle.label | index expression | +| main.go:51:3:51:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:51:3:51:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | +| main.go:51:3:51:22 | selection of Category | semmle.label | selection of Category | | main.go:52:11:52:11 | q | semmle.label | q | -| main.go:56:2:56:12 | definition of RequestData [pointer, Category] : slice type | semmle.label | definition of RequestData [pointer, Category] : slice type | -| main.go:57:3:57:14 | star expression [Category] : slice type | semmle.label | star expression [Category] : slice type | -| main.go:57:4:57:14 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | -| main.go:57:28:57:34 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| main.go:57:28:57:54 | index expression : slice type | semmle.label | index expression : slice type | -| main.go:60:3:60:25 | selection of Category : slice type | semmle.label | selection of Category : slice type | -| main.go:60:4:60:15 | star expression [Category] : slice type | semmle.label | star expression [Category] : slice type | -| main.go:60:5:60:15 | RequestData [pointer, Category] : slice type | semmle.label | RequestData [pointer, Category] : slice type | +| main.go:56:2:56:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | +| main.go:57:3:57:14 | star expression [Category] | semmle.label | star expression [Category] | +| main.go:57:4:57:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:57:28:57:34 | selection of URL | semmle.label | selection of URL | +| main.go:57:28:57:54 | index expression | semmle.label | index expression | +| main.go:60:3:60:25 | selection of Category | semmle.label | selection of Category | +| main.go:60:4:60:15 | star expression [Category] | semmle.label | star expression [Category] | +| main.go:60:5:60:15 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:61:11:61:11 | q | semmle.label | q | -| mongoDB.go:40:20:40:30 | call to Referer : string | semmle.label | call to Referer : string | +| mongoDB.go:40:20:40:30 | call to Referer | semmle.label | call to Referer | | mongoDB.go:57:22:57:29 | pipeline | semmle.label | pipeline | | mongoDB.go:61:27:61:32 | filter | semmle.label | filter | | mongoDB.go:63:23:63:28 | filter | semmle.label | filter | @@ -123,28 +123,28 @@ nodes | mongoDB.go:81:18:81:25 | pipeline | semmle.label | pipeline | subpaths #select -| SqlInjection.go:12:11:12:11 | q | SqlInjection.go:11:3:11:9 | selection of URL : pointer type | SqlInjection.go:12:11:12:11 | q | This query depends on a $@. | SqlInjection.go:11:3:11:9 | selection of URL | user-provided value | -| issue48.go:22:11:22:12 | q3 | issue48.go:17:25:17:32 | selection of Body : ReadCloser | issue48.go:22:11:22:12 | q3 | This query depends on a $@. | issue48.go:17:25:17:32 | selection of Body | user-provided value | -| issue48.go:32:11:32:12 | q4 | issue48.go:27:26:27:33 | selection of Body : ReadCloser | issue48.go:32:11:32:12 | q4 | This query depends on a $@. | issue48.go:27:26:27:33 | selection of Body | user-provided value | -| issue48.go:41:11:41:12 | q5 | issue48.go:37:24:37:30 | selection of URL : pointer type | issue48.go:41:11:41:12 | q5 | This query depends on a $@. | issue48.go:37:24:37:30 | selection of URL | user-provided value | -| main.go:10:11:10:28 | index expression | main.go:10:11:10:16 | selection of Form : Values | main.go:10:11:10:28 | index expression | This query depends on a $@. | main.go:10:11:10:16 | selection of Form | user-provided value | -| main.go:14:11:14:84 | call to Sprintf | main.go:14:63:14:67 | selection of URL : pointer type | main.go:14:11:14:84 | call to Sprintf | This query depends on a $@. | main.go:14:63:14:67 | selection of URL | user-provided value | -| main.go:15:11:15:85 | call to Sprintf | main.go:15:63:15:70 | selection of Header : Header | main.go:15:11:15:85 | call to Sprintf | This query depends on a $@. | main.go:15:63:15:70 | selection of Header | user-provided value | -| main.go:34:11:34:11 | q | main.go:29:13:29:19 | selection of URL : pointer type | main.go:34:11:34:11 | q | This query depends on a $@. | main.go:29:13:29:19 | selection of URL | user-provided value | -| main.go:43:11:43:11 | q | main.go:39:25:39:31 | selection of URL : pointer type | main.go:43:11:43:11 | q | This query depends on a $@. | main.go:39:25:39:31 | selection of URL | user-provided value | -| main.go:52:11:52:11 | q | main.go:48:28:48:34 | selection of URL : pointer type | main.go:52:11:52:11 | q | This query depends on a $@. | main.go:48:28:48:34 | selection of URL | user-provided value | -| main.go:61:11:61:11 | q | main.go:57:28:57:34 | selection of URL : pointer type | main.go:61:11:61:11 | q | This query depends on a $@. | main.go:57:28:57:34 | selection of URL | user-provided value | -| mongoDB.go:57:22:57:29 | pipeline | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:57:22:57:29 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:61:27:61:32 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:61:27:61:32 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:63:23:63:28 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:63:23:63:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:64:22:64:27 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:64:22:64:27 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:66:32:66:37 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:66:32:66:37 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:69:17:69:22 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:69:17:69:22 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:70:20:70:25 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:70:20:70:25 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:71:29:71:34 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:71:29:71:34 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:72:30:72:35 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:72:30:72:35 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:73:29:73:34 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:73:29:73:34 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:78:23:78:28 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:78:23:78:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:79:23:79:28 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:79:23:79:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:80:22:80:27 | filter | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:80:22:80:27 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | -| mongoDB.go:81:18:81:25 | pipeline | mongoDB.go:40:20:40:30 | call to Referer : string | mongoDB.go:81:18:81:25 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| SqlInjection.go:12:11:12:11 | q | SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:12:11:12:11 | q | This query depends on a $@. | SqlInjection.go:11:3:11:9 | selection of URL | user-provided value | +| issue48.go:22:11:22:12 | q3 | issue48.go:17:25:17:32 | selection of Body | issue48.go:22:11:22:12 | q3 | This query depends on a $@. | issue48.go:17:25:17:32 | selection of Body | user-provided value | +| issue48.go:32:11:32:12 | q4 | issue48.go:27:26:27:33 | selection of Body | issue48.go:32:11:32:12 | q4 | This query depends on a $@. | issue48.go:27:26:27:33 | selection of Body | user-provided value | +| issue48.go:41:11:41:12 | q5 | issue48.go:37:24:37:30 | selection of URL | issue48.go:41:11:41:12 | q5 | This query depends on a $@. | issue48.go:37:24:37:30 | selection of URL | user-provided value | +| main.go:10:11:10:28 | index expression | main.go:10:11:10:16 | selection of Form | main.go:10:11:10:28 | index expression | This query depends on a $@. | main.go:10:11:10:16 | selection of Form | user-provided value | +| main.go:14:11:14:84 | call to Sprintf | main.go:14:63:14:67 | selection of URL | main.go:14:11:14:84 | call to Sprintf | This query depends on a $@. | main.go:14:63:14:67 | selection of URL | user-provided value | +| main.go:15:11:15:85 | call to Sprintf | main.go:15:63:15:70 | selection of Header | main.go:15:11:15:85 | call to Sprintf | This query depends on a $@. | main.go:15:63:15:70 | selection of Header | user-provided value | +| main.go:34:11:34:11 | q | main.go:29:13:29:19 | selection of URL | main.go:34:11:34:11 | q | This query depends on a $@. | main.go:29:13:29:19 | selection of URL | user-provided value | +| main.go:43:11:43:11 | q | main.go:39:25:39:31 | selection of URL | main.go:43:11:43:11 | q | This query depends on a $@. | main.go:39:25:39:31 | selection of URL | user-provided value | +| main.go:52:11:52:11 | q | main.go:48:28:48:34 | selection of URL | main.go:52:11:52:11 | q | This query depends on a $@. | main.go:48:28:48:34 | selection of URL | user-provided value | +| main.go:61:11:61:11 | q | main.go:57:28:57:34 | selection of URL | main.go:61:11:61:11 | q | This query depends on a $@. | main.go:57:28:57:34 | selection of URL | user-provided value | +| mongoDB.go:57:22:57:29 | pipeline | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:57:22:57:29 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:61:27:61:32 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:61:27:61:32 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:63:23:63:28 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:63:23:63:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:64:22:64:27 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:64:22:64:27 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:66:32:66:37 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:66:32:66:37 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:69:17:69:22 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:69:17:69:22 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:70:20:70:25 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:70:20:70:25 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:71:29:71:34 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:71:29:71:34 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:72:30:72:35 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:72:30:72:35 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:73:29:73:34 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:73:29:73:34 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:78:23:78:28 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:78:23:78:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:79:23:79:28 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:79:23:79:28 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:80:22:80:27 | filter | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:80:22:80:27 | filter | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | +| mongoDB.go:81:18:81:25 | pipeline | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected index cf3f362ead9..52c76ed52ce 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected @@ -1,20 +1,20 @@ edges -| StringBreak.go:10:2:10:40 | ... := ...[0] : slice type | StringBreak.go:14:47:14:57 | versionJSON | -| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] : slice type | StringBreakMismatched.go:13:29:13:47 | type conversion : slice type | -| StringBreakMismatched.go:13:29:13:47 | type conversion : slice type | StringBreakMismatched.go:17:26:17:32 | escaped | -| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] : slice type | StringBreakMismatched.go:25:29:25:47 | type conversion : slice type | -| StringBreakMismatched.go:25:29:25:47 | type conversion : slice type | StringBreakMismatched.go:29:27:29:33 | escaped | +| StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | +| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:13:29:13:47 | type conversion | +| StringBreakMismatched.go:13:29:13:47 | type conversion | StringBreakMismatched.go:17:26:17:32 | escaped | +| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:25:29:25:47 | type conversion | +| StringBreakMismatched.go:25:29:25:47 | type conversion | StringBreakMismatched.go:29:27:29:33 | escaped | nodes -| StringBreak.go:10:2:10:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| StringBreak.go:10:2:10:40 | ... := ...[0] | semmle.label | ... := ...[0] | | StringBreak.go:14:47:14:57 | versionJSON | semmle.label | versionJSON | -| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | -| StringBreakMismatched.go:13:29:13:47 | type conversion : slice type | semmle.label | type conversion : slice type | +| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:13:29:13:47 | type conversion | semmle.label | type conversion | | StringBreakMismatched.go:17:26:17:32 | escaped | semmle.label | escaped | -| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | -| StringBreakMismatched.go:25:29:25:47 | type conversion : slice type | semmle.label | type conversion : slice type | +| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:25:29:25:47 | type conversion | semmle.label | type conversion | | StringBreakMismatched.go:29:27:29:33 | escaped | semmle.label | escaped | subpaths #select -| StringBreak.go:14:47:14:57 | versionJSON | StringBreak.go:10:2:10:40 | ... := ...[0] : slice type | StringBreak.go:14:47:14:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:10:2:10:40 | ... := ...[0] | JSON value | -| StringBreakMismatched.go:17:26:17:32 | escaped | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] : slice type | StringBreakMismatched.go:17:26:17:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | JSON value | -| StringBreakMismatched.go:29:27:29:33 | escaped | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] : slice type | StringBreakMismatched.go:29:27:29:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | JSON value | +| StringBreak.go:14:47:14:57 | versionJSON | StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:10:2:10:40 | ... := ...[0] | JSON value | +| StringBreakMismatched.go:17:26:17:32 | escaped | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:17:26:17:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | JSON value | +| StringBreakMismatched.go:29:27:29:33 | escaped | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:29:27:29:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | JSON value | diff --git a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected index 474cc5aa42c..4dd0a7d7cf4 100644 --- a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected +++ b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected @@ -1,42 +1,42 @@ edges -| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] : slice type | AllocationSizeOverflow.go:10:10:10:22 | call to len | -| tst2.go:9:2:9:37 | ... := ...[0] : slice type | tst2.go:10:22:10:30 | call to len | -| tst2.go:14:2:14:29 | ... := ...[0] : slice type | tst2.go:15:22:15:30 | call to len | -| tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:7:22:7:34 | call to len | -| tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:24:16:24:28 | call to len | -| tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:32:16:32:28 | call to len | -| tst.go:14:2:14:30 | ... = ...[0] : slice type | tst.go:15:22:15:34 | call to len | -| tst.go:20:2:20:31 | ... = ...[0] : slice type | tst.go:21:22:21:34 | call to len | -| tst.go:26:2:26:31 | ... = ...[0] : slice type | tst.go:27:26:27:38 | call to len | -| tst.go:34:2:34:30 | ... = ...[0] : slice type | tst.go:35:22:35:34 | call to len | +| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | AllocationSizeOverflow.go:10:10:10:22 | call to len | +| tst2.go:9:2:9:37 | ... := ...[0] | tst2.go:10:22:10:30 | call to len | +| tst2.go:14:2:14:29 | ... := ...[0] | tst2.go:15:22:15:30 | call to len | +| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:22:7:34 | call to len | +| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:24:16:24:28 | call to len | +| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:32:16:32:28 | call to len | +| tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:22:15:34 | call to len | +| tst.go:20:2:20:31 | ... = ...[0] | tst.go:21:22:21:34 | call to len | +| tst.go:26:2:26:31 | ... = ...[0] | tst.go:27:26:27:38 | call to len | +| tst.go:34:2:34:30 | ... = ...[0] | tst.go:35:22:35:34 | call to len | nodes -| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | semmle.label | ... := ...[0] | | AllocationSizeOverflow.go:10:10:10:22 | call to len | semmle.label | call to len | -| tst2.go:9:2:9:37 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| tst2.go:9:2:9:37 | ... := ...[0] | semmle.label | ... := ...[0] | | tst2.go:10:22:10:30 | call to len | semmle.label | call to len | -| tst2.go:14:2:14:29 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| tst2.go:14:2:14:29 | ... := ...[0] | semmle.label | ... := ...[0] | | tst2.go:15:22:15:30 | call to len | semmle.label | call to len | -| tst3.go:6:2:6:31 | ... := ...[0] : slice type | semmle.label | ... := ...[0] : slice type | +| tst3.go:6:2:6:31 | ... := ...[0] | semmle.label | ... := ...[0] | | tst3.go:7:22:7:34 | call to len | semmle.label | call to len | | tst3.go:24:16:24:28 | call to len | semmle.label | call to len | | tst3.go:32:16:32:28 | call to len | semmle.label | call to len | -| tst.go:14:2:14:30 | ... = ...[0] : slice type | semmle.label | ... = ...[0] : slice type | +| tst.go:14:2:14:30 | ... = ...[0] | semmle.label | ... = ...[0] | | tst.go:15:22:15:34 | call to len | semmle.label | call to len | -| tst.go:20:2:20:31 | ... = ...[0] : slice type | semmle.label | ... = ...[0] : slice type | +| tst.go:20:2:20:31 | ... = ...[0] | semmle.label | ... = ...[0] | | tst.go:21:22:21:34 | call to len | semmle.label | call to len | -| tst.go:26:2:26:31 | ... = ...[0] : slice type | semmle.label | ... = ...[0] : slice type | +| tst.go:26:2:26:31 | ... = ...[0] | semmle.label | ... = ...[0] | | tst.go:27:26:27:38 | call to len | semmle.label | call to len | -| tst.go:34:2:34:30 | ... = ...[0] : slice type | semmle.label | ... = ...[0] : slice type | +| tst.go:34:2:34:30 | ... = ...[0] | semmle.label | ... = ...[0] | | tst.go:35:22:35:34 | call to len | semmle.label | call to len | subpaths #select -| AllocationSizeOverflow.go:10:10:10:22 | call to len | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] : slice type | AllocationSizeOverflow.go:10:10:10:22 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | AllocationSizeOverflow.go:11:25:11:28 | size | allocation | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] : slice type | potentially large value | -| tst2.go:10:22:10:30 | call to len | tst2.go:9:2:9:37 | ... := ...[0] : slice type | tst2.go:10:22:10:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:10:22:10:32 | ...+... | allocation | tst2.go:9:2:9:37 | ... := ...[0] : slice type | potentially large value | -| tst2.go:15:22:15:30 | call to len | tst2.go:14:2:14:29 | ... := ...[0] : slice type | tst2.go:15:22:15:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:15:22:15:32 | ...+... | allocation | tst2.go:14:2:14:29 | ... := ...[0] : slice type | potentially large value | -| tst3.go:7:22:7:34 | call to len | tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:7:22:7:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:7:22:7:36 | ...+... | allocation | tst3.go:6:2:6:31 | ... := ...[0] : slice type | potentially large value | -| tst3.go:24:16:24:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:24:16:24:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:27:24:27:32 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] : slice type | potentially large value | -| tst3.go:32:16:32:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] : slice type | tst3.go:32:16:32:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:36:23:36:31 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] : slice type | potentially large value | -| tst.go:15:22:15:34 | call to len | tst.go:14:2:14:30 | ... = ...[0] : slice type | tst.go:15:22:15:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:15:22:15:36 | ...+... | allocation | tst.go:14:2:14:30 | ... = ...[0] : slice type | potentially large value | -| tst.go:21:22:21:34 | call to len | tst.go:20:2:20:31 | ... = ...[0] : slice type | tst.go:21:22:21:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:21:22:21:36 | ...+... | allocation | tst.go:20:2:20:31 | ... = ...[0] : slice type | potentially large value | -| tst.go:27:26:27:38 | call to len | tst.go:26:2:26:31 | ... = ...[0] : slice type | tst.go:27:26:27:38 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:27:26:27:40 | ...+... | allocation | tst.go:26:2:26:31 | ... = ...[0] : slice type | potentially large value | -| tst.go:35:22:35:34 | call to len | tst.go:34:2:34:30 | ... = ...[0] : slice type | tst.go:35:22:35:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:35:22:35:36 | ...+... | allocation | tst.go:34:2:34:30 | ... = ...[0] : slice type | potentially large value | +| AllocationSizeOverflow.go:10:10:10:22 | call to len | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | AllocationSizeOverflow.go:10:10:10:22 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | AllocationSizeOverflow.go:11:25:11:28 | size | allocation | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | potentially large value | +| tst2.go:10:22:10:30 | call to len | tst2.go:9:2:9:37 | ... := ...[0] | tst2.go:10:22:10:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:10:22:10:32 | ...+... | allocation | tst2.go:9:2:9:37 | ... := ...[0] | potentially large value | +| tst2.go:15:22:15:30 | call to len | tst2.go:14:2:14:29 | ... := ...[0] | tst2.go:15:22:15:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:15:22:15:32 | ...+... | allocation | tst2.go:14:2:14:29 | ... := ...[0] | potentially large value | +| tst3.go:7:22:7:34 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:22:7:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:7:22:7:36 | ...+... | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value | +| tst3.go:24:16:24:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:24:16:24:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:27:24:27:32 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value | +| tst3.go:32:16:32:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:32:16:32:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:36:23:36:31 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value | +| tst.go:15:22:15:34 | call to len | tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:22:15:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:15:22:15:36 | ...+... | allocation | tst.go:14:2:14:30 | ... = ...[0] | potentially large value | +| tst.go:21:22:21:34 | call to len | tst.go:20:2:20:31 | ... = ...[0] | tst.go:21:22:21:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:21:22:21:36 | ...+... | allocation | tst.go:20:2:20:31 | ... = ...[0] | potentially large value | +| tst.go:27:26:27:38 | call to len | tst.go:26:2:26:31 | ... = ...[0] | tst.go:27:26:27:38 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:27:26:27:40 | ...+... | allocation | tst.go:26:2:26:31 | ... = ...[0] | potentially large value | +| tst.go:35:22:35:34 | call to len | tst.go:34:2:34:30 | ... = ...[0] | tst.go:35:22:35:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:35:22:35:36 | ...+... | allocation | tst.go:34:2:34:30 | ... = ...[0] | potentially large value | diff --git a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index ff8c7a9f72f..99042f7a497 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,8 +1,8 @@ edges -| test.go:14:2:14:4 | definition of buf : slice type | test.go:17:10:17:12 | buf | +| test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | nodes -| test.go:14:2:14:4 | definition of buf : slice type | semmle.label | definition of buf : slice type | +| test.go:14:2:14:4 | definition of buf | semmle.label | definition of buf | | test.go:17:10:17:12 | buf | semmle.label | buf | subpaths #select -| test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf : slice type | test.go:17:10:17:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:14:2:14:4 | definition of buf | stack trace information | +| test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:14:2:14:4 | definition of buf | stack trace information | diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 8d66b76c863..5daa517378e 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,135 +1,135 @@ edges -| klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | -| klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | -| main.go:21:19:21:26 | password : string | main.go:22:29:22:34 | fields | -| overrides.go:9:9:9:16 | password : string | overrides.go:13:14:13:23 | call to String | -| passwords.go:8:12:8:12 | definition of x : string | passwords.go:9:14:9:14 | x | -| passwords.go:30:8:30:15 | password : string | passwords.go:8:12:8:12 | definition of x : string | -| passwords.go:34:28:34:35 | password : string | passwords.go:34:14:34:35 | ...+... | -| passwords.go:37:13:37:13 | x : string | passwords.go:39:14:39:17 | obj1 | -| passwords.go:42:6:42:13 | password : string | passwords.go:44:14:44:17 | obj2 | -| passwords.go:48:11:48:18 | password : string | passwords.go:47:14:47:17 | obj3 | -| passwords.go:86:16:86:36 | call to make : map type | passwords.go:88:14:88:26 | utilityObject | -| passwords.go:90:12:90:19 | password : string | passwords.go:91:23:91:28 | secret | -| passwords.go:101:33:101:40 | password : string | passwords.go:101:15:101:40 | ...+... | -| passwords.go:107:34:107:41 | password : string | passwords.go:107:16:107:41 | ...+... | -| passwords.go:112:33:112:40 | password : string | passwords.go:112:15:112:40 | ...+... | -| passwords.go:116:28:116:36 | password1 : stringable | passwords.go:116:14:116:45 | ...+... | -| passwords.go:118:12:123:2 | struct literal [x] : string | passwords.go:126:14:126:19 | config [x] : string | -| passwords.go:118:12:123:2 | struct literal [y] : string | passwords.go:127:14:127:19 | config [y] : string | -| passwords.go:119:13:119:13 | x : string | passwords.go:125:14:125:19 | config | -| passwords.go:121:13:121:20 | password : string | passwords.go:118:12:123:2 | struct literal [x] : string | -| passwords.go:121:13:121:20 | password : string | passwords.go:125:14:125:19 | config | -| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:118:12:123:2 | struct literal [y] : string | -| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config | -| passwords.go:126:14:126:19 | config [x] : string | passwords.go:126:14:126:21 | selection of x | -| passwords.go:127:14:127:19 | config [y] : string | passwords.go:127:14:127:21 | selection of y | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | protobuf.go:12:2:12:6 | query [pointer, Description] : string | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | protobuf.go:14:14:14:18 | query [pointer, Description] : string | -| protobuf.go:12:2:12:6 | implicit dereference [Description] : string | protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | -| protobuf.go:12:2:12:6 | query [pointer, Description] : string | protobuf.go:12:2:12:6 | implicit dereference [Description] : string | -| protobuf.go:12:22:12:29 | password : string | protobuf.go:12:2:12:6 | implicit dereference [Description] : string | -| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protobuf.go:14:14:14:35 | call to GetDescription | -| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | -| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string | -| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | -| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string | -| util.go:16:9:16:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword | +| klog.go:20:30:20:37 | selection of Header | klog.go:22:15:22:20 | header | +| klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | +| main.go:21:19:21:26 | password | main.go:22:29:22:34 | fields | +| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | +| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | +| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | +| passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | +| passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 | +| passwords.go:42:6:42:13 | password | passwords.go:44:14:44:17 | obj2 | +| passwords.go:48:11:48:18 | password | passwords.go:47:14:47:17 | obj3 | +| passwords.go:86:16:86:36 | call to make | passwords.go:88:14:88:26 | utilityObject | +| passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret | +| passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... | +| passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | +| passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | +| passwords.go:116:28:116:36 | password1 | passwords.go:116:14:116:45 | ...+... | +| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:126:14:126:19 | config [x] | +| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | config [y] | +| passwords.go:119:13:119:13 | x | passwords.go:125:14:125:19 | config | +| passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal [x] | +| passwords.go:121:13:121:20 | password | passwords.go:125:14:125:19 | config | +| passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal [y] | +| passwords.go:122:13:122:25 | call to getPassword | passwords.go:125:14:125:19 | config | +| passwords.go:126:14:126:19 | config [x] | passwords.go:126:14:126:21 | selection of x | +| passwords.go:127:14:127:19 | config [y] | passwords.go:127:14:127:21 | selection of y | +| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:12:2:12:6 | query [pointer, Description] | +| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | +| protobuf.go:12:2:12:6 | implicit dereference [Description] | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | +| protobuf.go:12:2:12:6 | query [pointer, Description] | protobuf.go:12:2:12:6 | implicit dereference [Description] | +| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [Description] | +| protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | +| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | +| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | +| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | +| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | +| util.go:16:9:16:18 | selection of password | passwords.go:28:14:28:28 | call to getPassword | nodes -| klog.go:20:30:20:37 | selection of Header : Header | semmle.label | selection of Header : Header | +| klog.go:20:30:20:37 | selection of Header | semmle.label | selection of Header | | klog.go:22:15:22:20 | header | semmle.label | header | -| klog.go:28:13:28:20 | selection of Header : Header | semmle.label | selection of Header : Header | +| klog.go:28:13:28:20 | selection of Header | semmle.label | selection of Header | | klog.go:28:13:28:41 | call to Get | semmle.label | call to Get | | main.go:15:14:15:21 | password | semmle.label | password | | main.go:17:12:17:19 | password | semmle.label | password | | main.go:18:17:18:24 | password | semmle.label | password | -| main.go:21:19:21:26 | password : string | semmle.label | password : string | +| main.go:21:19:21:26 | password | semmle.label | password | | main.go:22:29:22:34 | fields | semmle.label | fields | | main.go:25:35:25:42 | password | semmle.label | password | -| overrides.go:9:9:9:16 | password : string | semmle.label | password : string | +| overrides.go:9:9:9:16 | password | semmle.label | password | | overrides.go:13:14:13:23 | call to String | semmle.label | call to String | -| passwords.go:8:12:8:12 | definition of x : string | semmle.label | definition of x : string | +| passwords.go:8:12:8:12 | definition of x | semmle.label | definition of x | | passwords.go:9:14:9:14 | x | semmle.label | x | | passwords.go:25:14:25:21 | password | semmle.label | password | | passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password | | passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword | | passwords.go:28:14:28:28 | call to getPassword | semmle.label | call to getPassword | -| passwords.go:30:8:30:15 | password : string | semmle.label | password : string | +| passwords.go:30:8:30:15 | password | semmle.label | password | | passwords.go:32:12:32:19 | password | semmle.label | password | | passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... | -| passwords.go:34:28:34:35 | password : string | semmle.label | password : string | -| passwords.go:37:13:37:13 | x : string | semmle.label | x : string | +| passwords.go:34:28:34:35 | password | semmle.label | password | +| passwords.go:37:13:37:13 | x | semmle.label | x | | passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 | -| passwords.go:42:6:42:13 | password : string | semmle.label | password : string | +| passwords.go:42:6:42:13 | password | semmle.label | password | | passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 | | passwords.go:47:14:47:17 | obj3 | semmle.label | obj3 | -| passwords.go:48:11:48:18 | password : string | semmle.label | password : string | +| passwords.go:48:11:48:18 | password | semmle.label | password | | passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | -| passwords.go:86:16:86:36 | call to make : map type | semmle.label | call to make : map type | +| passwords.go:86:16:86:36 | call to make | semmle.label | call to make | | passwords.go:88:14:88:26 | utilityObject | semmle.label | utilityObject | -| passwords.go:90:12:90:19 | password : string | semmle.label | password : string | +| passwords.go:90:12:90:19 | password | semmle.label | password | | passwords.go:91:23:91:28 | secret | semmle.label | secret | | passwords.go:101:15:101:40 | ...+... | semmle.label | ...+... | -| passwords.go:101:33:101:40 | password : string | semmle.label | password : string | +| passwords.go:101:33:101:40 | password | semmle.label | password | | passwords.go:107:16:107:41 | ...+... | semmle.label | ...+... | -| passwords.go:107:34:107:41 | password : string | semmle.label | password : string | +| passwords.go:107:34:107:41 | password | semmle.label | password | | passwords.go:112:15:112:40 | ...+... | semmle.label | ...+... | -| passwords.go:112:33:112:40 | password : string | semmle.label | password : string | +| passwords.go:112:33:112:40 | password | semmle.label | password | | passwords.go:116:14:116:45 | ...+... | semmle.label | ...+... | -| passwords.go:116:28:116:36 | password1 : stringable | semmle.label | password1 : stringable | -| passwords.go:118:12:123:2 | struct literal [x] : string | semmle.label | struct literal [x] : string | -| passwords.go:118:12:123:2 | struct literal [y] : string | semmle.label | struct literal [y] : string | -| passwords.go:119:13:119:13 | x : string | semmle.label | x : string | -| passwords.go:121:13:121:20 | password : string | semmle.label | password : string | -| passwords.go:122:13:122:25 | call to getPassword : string | semmle.label | call to getPassword : string | +| passwords.go:116:28:116:36 | password1 | semmle.label | password1 | +| passwords.go:118:12:123:2 | struct literal [x] | semmle.label | struct literal [x] | +| passwords.go:118:12:123:2 | struct literal [y] | semmle.label | struct literal [y] | +| passwords.go:119:13:119:13 | x | semmle.label | x | +| passwords.go:121:13:121:20 | password | semmle.label | password | +| passwords.go:122:13:122:25 | call to getPassword | semmle.label | call to getPassword | | passwords.go:125:14:125:19 | config | semmle.label | config | -| passwords.go:126:14:126:19 | config [x] : string | semmle.label | config [x] : string | +| passwords.go:126:14:126:19 | config [x] | semmle.label | config [x] | | passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x | -| passwords.go:127:14:127:19 | config [y] : string | semmle.label | config [y] : string | +| passwords.go:127:14:127:19 | config [y] | semmle.label | config [y] | | passwords.go:127:14:127:21 | selection of y | semmle.label | selection of y | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | semmle.label | definition of query [pointer, Description] : string | -| protobuf.go:12:2:12:6 | implicit dereference [Description] : string | semmle.label | implicit dereference [Description] : string | -| protobuf.go:12:2:12:6 | query [pointer, Description] : string | semmle.label | query [pointer, Description] : string | -| protobuf.go:12:22:12:29 | password : string | semmle.label | password : string | -| protobuf.go:14:14:14:18 | query [pointer, Description] : string | semmle.label | query [pointer, Description] : string | +| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | semmle.label | definition of query [pointer, Description] | +| protobuf.go:12:2:12:6 | implicit dereference [Description] | semmle.label | implicit dereference [Description] | +| protobuf.go:12:2:12:6 | query [pointer, Description] | semmle.label | query [pointer, Description] | +| protobuf.go:12:22:12:29 | password | semmle.label | password | +| protobuf.go:14:14:14:18 | query [pointer, Description] | semmle.label | query [pointer, Description] | | protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription | -| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | semmle.label | definition of x [pointer, Description] : string | -| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string | semmle.label | implicit dereference [Description] : string | -| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string | semmle.label | x [pointer, Description] : string | -| protos/query/query.pb.go:119:10:119:22 | selection of Description : string | semmle.label | selection of Description : string | -| util.go:16:9:16:18 | selection of password : string | semmle.label | selection of password : string | +| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | semmle.label | definition of x [pointer, Description] | +| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | semmle.label | implicit dereference [Description] | +| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | semmle.label | x [pointer, Description] | +| protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description | +| util.go:16:9:16:18 | selection of password | semmle.label | selection of password | subpaths -| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | protobuf.go:14:14:14:35 | call to GetDescription : string | +| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription | #select -| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers | -| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers | +| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers | +| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers | | main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | $@ flows to a logging call. | main.go:15:14:15:21 | password | Sensitive data returned by an access to password | | main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | $@ flows to a logging call. | main.go:17:12:17:19 | password | Sensitive data returned by an access to password | | main.go:18:17:18:24 | password | main.go:18:17:18:24 | password | main.go:18:17:18:24 | password | $@ flows to a logging call. | main.go:18:17:18:24 | password | Sensitive data returned by an access to password | -| main.go:22:29:22:34 | fields | main.go:21:19:21:26 | password : string | main.go:22:29:22:34 | fields | $@ flows to a logging call. | main.go:21:19:21:26 | password | Sensitive data returned by an access to password | +| main.go:22:29:22:34 | fields | main.go:21:19:21:26 | password | main.go:22:29:22:34 | fields | $@ flows to a logging call. | main.go:21:19:21:26 | password | Sensitive data returned by an access to password | | main.go:25:35:25:42 | password | main.go:25:35:25:42 | password | main.go:25:35:25:42 | password | $@ flows to a logging call. | main.go:25:35:25:42 | password | Sensitive data returned by an access to password | -| overrides.go:13:14:13:23 | call to String | overrides.go:9:9:9:16 | password : string | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:9:9:9:16 | password | Sensitive data returned by an access to password | -| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password : string | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:30:8:30:15 | password | Sensitive data returned by an access to password | +| overrides.go:13:14:13:23 | call to String | overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:9:9:9:16 | password | Sensitive data returned by an access to password | +| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:30:8:30:15 | password | Sensitive data returned by an access to password | | passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:25:14:25:21 | password | Sensitive data returned by an access to password | | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password | | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword | | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword | -| passwords.go:28:14:28:28 | call to getPassword | util.go:16:9:16:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | util.go:16:9:16:18 | selection of password | Sensitive data returned by an access to password | +| passwords.go:28:14:28:28 | call to getPassword | util.go:16:9:16:18 | selection of password | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | util.go:16:9:16:18 | selection of password | Sensitive data returned by an access to password | | passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | $@ flows to a logging call. | passwords.go:32:12:32:19 | password | Sensitive data returned by an access to password | -| passwords.go:34:14:34:35 | ...+... | passwords.go:34:28:34:35 | password : string | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:34:28:34:35 | password | Sensitive data returned by an access to password | -| passwords.go:39:14:39:17 | obj1 | passwords.go:37:13:37:13 | x : string | passwords.go:39:14:39:17 | obj1 | $@ flows to a logging call. | passwords.go:37:13:37:13 | x | Sensitive data returned by an access to password | -| passwords.go:44:14:44:17 | obj2 | passwords.go:42:6:42:13 | password : string | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:42:6:42:13 | password | Sensitive data returned by an access to password | -| passwords.go:47:14:47:17 | obj3 | passwords.go:48:11:48:18 | password : string | passwords.go:47:14:47:17 | obj3 | $@ flows to a logging call. | passwords.go:48:11:48:18 | password | Sensitive data returned by an access to password | +| passwords.go:34:14:34:35 | ...+... | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:34:28:34:35 | password | Sensitive data returned by an access to password | +| passwords.go:39:14:39:17 | obj1 | passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 | $@ flows to a logging call. | passwords.go:37:13:37:13 | x | Sensitive data returned by an access to password | +| passwords.go:44:14:44:17 | obj2 | passwords.go:42:6:42:13 | password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:42:6:42:13 | password | Sensitive data returned by an access to password | +| passwords.go:47:14:47:17 | obj3 | passwords.go:48:11:48:18 | password | passwords.go:47:14:47:17 | obj3 | $@ flows to a logging call. | passwords.go:48:11:48:18 | password | Sensitive data returned by an access to password | | passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:51:14:51:27 | fixed_password | Sensitive data returned by an access to fixed_password | -| passwords.go:88:14:88:26 | utilityObject | passwords.go:86:16:86:36 | call to make : map type | passwords.go:88:14:88:26 | utilityObject | $@ flows to a logging call. | passwords.go:86:16:86:36 | call to make | Sensitive data returned by an access to passwordSet | -| passwords.go:91:23:91:28 | secret | passwords.go:90:12:90:19 | password : string | passwords.go:91:23:91:28 | secret | $@ flows to a logging call. | passwords.go:90:12:90:19 | password | Sensitive data returned by an access to password | -| passwords.go:101:15:101:40 | ...+... | passwords.go:101:33:101:40 | password : string | passwords.go:101:15:101:40 | ...+... | $@ flows to a logging call. | passwords.go:101:33:101:40 | password | Sensitive data returned by an access to password | -| passwords.go:107:16:107:41 | ...+... | passwords.go:107:34:107:41 | password : string | passwords.go:107:16:107:41 | ...+... | $@ flows to a logging call. | passwords.go:107:34:107:41 | password | Sensitive data returned by an access to password | -| passwords.go:112:15:112:40 | ...+... | passwords.go:112:33:112:40 | password : string | passwords.go:112:15:112:40 | ...+... | $@ flows to a logging call. | passwords.go:112:33:112:40 | password | Sensitive data returned by an access to password | -| passwords.go:116:14:116:45 | ...+... | passwords.go:116:28:116:36 | password1 : stringable | passwords.go:116:14:116:45 | ...+... | $@ flows to a logging call. | passwords.go:116:28:116:36 | password1 | Sensitive data returned by an access to password1 | -| passwords.go:125:14:125:19 | config | passwords.go:119:13:119:13 | x : string | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:119:13:119:13 | x | Sensitive data returned by an access to password | -| passwords.go:125:14:125:19 | config | passwords.go:121:13:121:20 | password : string | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | -| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | -| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password : string | passwords.go:126:14:126:21 | selection of x | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | -| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | -| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password : string | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password | +| passwords.go:88:14:88:26 | utilityObject | passwords.go:86:16:86:36 | call to make | passwords.go:88:14:88:26 | utilityObject | $@ flows to a logging call. | passwords.go:86:16:86:36 | call to make | Sensitive data returned by an access to passwordSet | +| passwords.go:91:23:91:28 | secret | passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret | $@ flows to a logging call. | passwords.go:90:12:90:19 | password | Sensitive data returned by an access to password | +| passwords.go:101:15:101:40 | ...+... | passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... | $@ flows to a logging call. | passwords.go:101:33:101:40 | password | Sensitive data returned by an access to password | +| passwords.go:107:16:107:41 | ...+... | passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | $@ flows to a logging call. | passwords.go:107:34:107:41 | password | Sensitive data returned by an access to password | +| passwords.go:112:15:112:40 | ...+... | passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | $@ flows to a logging call. | passwords.go:112:33:112:40 | password | Sensitive data returned by an access to password | +| passwords.go:116:14:116:45 | ...+... | passwords.go:116:28:116:36 | password1 | passwords.go:116:14:116:45 | ...+... | $@ flows to a logging call. | passwords.go:116:28:116:36 | password1 | Sensitive data returned by an access to password1 | +| passwords.go:125:14:125:19 | config | passwords.go:119:13:119:13 | x | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:119:13:119:13 | x | Sensitive data returned by an access to password | +| passwords.go:125:14:125:19 | config | passwords.go:121:13:121:20 | password | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | +| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password | passwords.go:126:14:126:21 | selection of x | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | +| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password | diff --git a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected index e7fbbc39fb2..2376ab7a7cf 100644 --- a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected +++ b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected @@ -1,50 +1,48 @@ edges -| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal : signature type | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | -| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion : signature type | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | -| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | -| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : HostKeyCallback | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | -| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : signature type | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | -| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback : signature type | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | -| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] : HostKeyCallback | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | -| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion : signature type | InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback : signature type | -| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback : signature type | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : signature type | -| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion : signature type | InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback : signature type | -| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion : signature type | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback : signature type | -| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback : signature type | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : signature type | -| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey : HostKeyCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : HostKeyCallback | -| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback : signature type | InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback : signature type | +| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | +| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | +| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | +| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | +| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | +| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | +| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | +| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | +| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | +| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | +| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | +| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | +| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal | InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | +| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | +| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | +| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | nodes | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | semmle.label | type conversion | -| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal : signature type | semmle.label | function literal : signature type | +| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | semmle.label | function literal | | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey | -| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion : signature type | semmle.label | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal : signature type | semmle.label | function literal : signature type | +| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | semmle.label | type conversion | +| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | semmle.label | function literal | | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | semmle.label | callback | -| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal : signature type | semmle.label | function literal : signature type | +| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | semmle.label | function literal | | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | semmle.label | type conversion | -| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : HostKeyCallback | semmle.label | definition of callback : HostKeyCallback | -| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback : signature type | semmle.label | definition of callback : signature type | +| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | semmle.label | definition of callback | | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | semmle.label | callback | -| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback : signature type | semmle.label | definition of callback : signature type | +| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | semmle.label | definition of callback | | InsecureHostKeyCallbackExample.go:76:28:76:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey | | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | semmle.label | callback | | InsecureHostKeyCallbackExample.go:92:28:92:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey | -| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] : HostKeyCallback | semmle.label | ... := ...[0] : HostKeyCallback | +| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | semmle.label | ... := ...[0] | | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | semmle.label | callback | -| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion : signature type | semmle.label | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal : signature type | semmle.label | function literal : signature type | -| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback : signature type | semmle.label | insecureCallback : signature type | -| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion : signature type | semmle.label | type conversion : signature type | -| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal : signature type | semmle.label | function literal : signature type | -| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback : signature type | semmle.label | potentiallySecureCallback : signature type | -| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey : HostKeyCallback | semmle.label | call to InsecureIgnoreHostKey : HostKeyCallback | -| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback : signature type | semmle.label | potentiallySecureCallback : signature type | +| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | semmle.label | type conversion | +| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | semmle.label | function literal | +| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | semmle.label | insecureCallback | +| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | semmle.label | type conversion | +| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal | semmle.label | function literal | +| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | semmle.label | potentiallySecureCallback | +| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey | +| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | semmle.label | potentiallySecureCallback | subpaths #select -| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal : signature type | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | this source | +| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | this source | | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | this source | -| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | this source | -| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal : signature type | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | this source | +| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | this source | +| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | this source | diff --git a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected index fb9488b7165..fb1058af01c 100644 --- a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected +++ b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected @@ -1,28 +1,28 @@ edges -| InsufficientKeySize.go:13:10:13:13 | 1024 : int | InsufficientKeySize.go:14:31:14:34 | size | -| InsufficientKeySize.go:18:7:18:10 | 1024 : int | InsufficientKeySize.go:25:11:25:14 | definition of size : int | -| InsufficientKeySize.go:25:11:25:14 | definition of size : int | InsufficientKeySize.go:26:31:26:34 | size | -| InsufficientKeySize.go:30:13:30:16 | 1024 : int | InsufficientKeySize.go:32:32:32:38 | keyBits | -| InsufficientKeySize.go:44:13:44:16 | 1024 : int | InsufficientKeySize.go:47:32:47:38 | keyBits | -| InsufficientKeySize.go:61:21:61:24 | 1024 : int | InsufficientKeySize.go:67:31:67:37 | keyBits | +| InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | +| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:11:25:14 | definition of size | +| InsufficientKeySize.go:25:11:25:14 | definition of size | InsufficientKeySize.go:26:31:26:34 | size | +| InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | +| InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | +| InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | nodes | InsufficientKeySize.go:9:31:9:34 | 1024 | semmle.label | 1024 | -| InsufficientKeySize.go:13:10:13:13 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:13:10:13:13 | 1024 | semmle.label | 1024 | | InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size | -| InsufficientKeySize.go:18:7:18:10 | 1024 : int | semmle.label | 1024 : int | -| InsufficientKeySize.go:25:11:25:14 | definition of size : int | semmle.label | definition of size : int | +| InsufficientKeySize.go:18:7:18:10 | 1024 | semmle.label | 1024 | +| InsufficientKeySize.go:25:11:25:14 | definition of size | semmle.label | definition of size | | InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size | -| InsufficientKeySize.go:30:13:30:16 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:30:13:30:16 | 1024 | semmle.label | 1024 | | InsufficientKeySize.go:32:32:32:38 | keyBits | semmle.label | keyBits | -| InsufficientKeySize.go:44:13:44:16 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:44:13:44:16 | 1024 | semmle.label | 1024 | | InsufficientKeySize.go:47:32:47:38 | keyBits | semmle.label | keyBits | -| InsufficientKeySize.go:61:21:61:24 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:61:21:61:24 | 1024 | semmle.label | 1024 | | InsufficientKeySize.go:67:31:67:37 | keyBits | semmle.label | keyBits | subpaths #select | InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | The size of this RSA key should be at least 2048 bits. | -| InsufficientKeySize.go:14:31:14:34 | size | InsufficientKeySize.go:13:10:13:13 | 1024 : int | InsufficientKeySize.go:14:31:14:34 | size | The size of this RSA key should be at least 2048 bits. | -| InsufficientKeySize.go:26:31:26:34 | size | InsufficientKeySize.go:18:7:18:10 | 1024 : int | InsufficientKeySize.go:26:31:26:34 | size | The size of this RSA key should be at least 2048 bits. | -| InsufficientKeySize.go:32:32:32:38 | keyBits | InsufficientKeySize.go:30:13:30:16 | 1024 : int | InsufficientKeySize.go:32:32:32:38 | keyBits | The size of this RSA key should be at least 2048 bits. | -| InsufficientKeySize.go:47:32:47:38 | keyBits | InsufficientKeySize.go:44:13:44:16 | 1024 : int | InsufficientKeySize.go:47:32:47:38 | keyBits | The size of this RSA key should be at least 2048 bits. | -| InsufficientKeySize.go:67:31:67:37 | keyBits | InsufficientKeySize.go:61:21:61:24 | 1024 : int | InsufficientKeySize.go:67:31:67:37 | keyBits | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:14:31:14:34 | size | InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:26:31:26:34 | size | InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:26:31:26:34 | size | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:32:32:32:38 | keyBits | InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:47:32:47:38 | keyBits | InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:67:31:67:37 | keyBits | InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | The size of this RSA key should be at least 2048 bits. | diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected index 6ae0010ec99..ba37534511a 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected @@ -1,49 +1,35 @@ edges -| UnsafeTLS.go:131:14:131:29 | selection of VersionTLS13 : uint16 | UnsafeTLS.go:136:16:136:22 | version | -| UnsafeTLS.go:133:14:133:29 | selection of VersionSSL30 : uint16 | UnsafeTLS.go:136:16:136:22 | version | -| UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | -| UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:272:18:274:4 | slice literal | -| UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:280:18:282:4 | slice literal | -| UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:288:18:290:4 | slice literal | -| UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:296:18:298:4 | slice literal | -| UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:304:18:306:4 | slice literal | -| UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:312:18:314:4 | slice literal | -| UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:329:25:329:94 | call to append | -| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:336:26:336:58 | call to append | -| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | UnsafeTLS.go:336:26:336:58 | call to append | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | -| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | -| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:346:25:346:36 | cipherSuites | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | UnsafeTLS.go:346:25:346:36 | cipherSuites | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:355:25:355:36 | cipherSuites | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | UnsafeTLS.go:355:25:355:36 | cipherSuites | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:353:40:353:48 | index expression : pointer type | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | UnsafeTLS.go:355:25:355:36 | cipherSuites | -| UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:362:18:364:4 | slice literal | -| UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:370:18:372:4 | slice literal | -| UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:378:18:380:4 | slice literal | -| UnsafeTLS.go:387:5:387:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:386:18:388:4 | slice literal | -| UnsafeTLS.go:395:5:395:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:394:18:396:4 | slice literal | -| UnsafeTLS.go:403:4:403:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:402:33:404:3 | slice literal | -| UnsafeTLS.go:410:4:410:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:409:31:411:3 | slice literal | -| UnsafeTLS.go:419:6:419:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:418:19:420:5 | slice literal | -| UnsafeTLS.go:426:6:426:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:425:19:427:5 | slice literal | -| UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:432:19:434:5 | slice literal | -| UnsafeTLS.go:443:6:443:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:442:19:444:5 | slice literal | -| UnsafeTLS.go:450:6:450:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:449:19:451:5 | slice literal | -| UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:456:19:458:5 | slice literal | +| UnsafeTLS.go:131:14:131:29 | selection of VersionTLS13 | UnsafeTLS.go:136:16:136:22 | version | +| UnsafeTLS.go:133:14:133:29 | selection of VersionSSL30 | UnsafeTLS.go:136:16:136:22 | version | +| UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | +| UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:272:18:274:4 | slice literal | +| UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:280:18:282:4 | slice literal | +| UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | UnsafeTLS.go:288:18:290:4 | slice literal | +| UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:296:18:298:4 | slice literal | +| UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:304:18:306:4 | slice literal | +| UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:312:18:314:4 | slice literal | +| UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:329:25:329:94 | call to append | +| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | UnsafeTLS.go:336:26:336:58 | call to append | +| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | UnsafeTLS.go:346:25:346:36 | cipherSuites | +| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | UnsafeTLS.go:355:25:355:36 | cipherSuites | +| UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:362:18:364:4 | slice literal | +| UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:370:18:372:4 | slice literal | +| UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:378:18:380:4 | slice literal | +| UnsafeTLS.go:387:5:387:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:386:18:388:4 | slice literal | +| UnsafeTLS.go:395:5:395:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:394:18:396:4 | slice literal | +| UnsafeTLS.go:403:4:403:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:402:33:404:3 | slice literal | +| UnsafeTLS.go:410:4:410:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:409:31:411:3 | slice literal | +| UnsafeTLS.go:419:6:419:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:418:19:420:5 | slice literal | +| UnsafeTLS.go:426:6:426:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:425:19:427:5 | slice literal | +| UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:432:19:434:5 | slice literal | +| UnsafeTLS.go:443:6:443:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:442:19:444:5 | slice literal | +| UnsafeTLS.go:450:6:450:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:449:19:451:5 | slice literal | +| UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:456:19:458:5 | slice literal | nodes | UnsafeTLS.go:21:23:21:23 | 0 | semmle.label | 0 | | UnsafeTLS.go:25:23:25:23 | 0 | semmle.label | 0 | @@ -64,8 +50,8 @@ nodes | UnsafeTLS.go:111:16:111:16 | 0 | semmle.label | 0 | | UnsafeTLS.go:117:16:117:16 | 0 | semmle.label | 0 | | UnsafeTLS.go:123:16:123:16 | 0 | semmle.label | 0 | -| UnsafeTLS.go:131:14:131:29 | selection of VersionTLS13 : uint16 | semmle.label | selection of VersionTLS13 : uint16 | -| UnsafeTLS.go:133:14:133:29 | selection of VersionSSL30 : uint16 | semmle.label | selection of VersionSSL30 : uint16 | +| UnsafeTLS.go:131:14:131:29 | selection of VersionTLS13 | semmle.label | selection of VersionTLS13 | +| UnsafeTLS.go:133:14:133:29 | selection of VersionSSL30 | semmle.label | selection of VersionSSL30 | | UnsafeTLS.go:136:16:136:22 | version | semmle.label | version | | UnsafeTLS.go:144:24:144:39 | selection of VersionTLS13 | semmle.label | selection of VersionTLS13 | | UnsafeTLS.go:146:24:146:39 | selection of VersionSSL30 | semmle.label | selection of VersionSSL30 | @@ -86,62 +72,58 @@ nodes | UnsafeTLS.go:243:16:243:16 | 0 | semmle.label | 0 | | UnsafeTLS.go:250:16:250:16 | 0 | semmle.label | 0 | | UnsafeTLS.go:259:18:266:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | -| UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | -| UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | -| UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | -| UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | -| UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA | +| UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | +| UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | +| UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | +| UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | +| UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:272:18:274:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA | | UnsafeTLS.go:280:18:282:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:288:18:290:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | | UnsafeTLS.go:296:18:298:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | | UnsafeTLS.go:304:18:306:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:312:18:314:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:329:25:329:94 | call to append | semmle.label | call to append | -| UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | -| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | +| UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | +| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | | UnsafeTLS.go:336:26:336:58 | call to append | semmle.label | call to append | -| UnsafeTLS.go:336:54:336:54 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | -| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | -| UnsafeTLS.go:344:40:344:40 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | +| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | | UnsafeTLS.go:346:25:346:36 | cipherSuites | semmle.label | cipherSuites | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | -| UnsafeTLS.go:353:40:353:48 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | -| UnsafeTLS.go:353:40:353:48 | index expression : pointer type | semmle.label | index expression : pointer type | +| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | | UnsafeTLS.go:355:25:355:36 | cipherSuites | semmle.label | cipherSuites | | UnsafeTLS.go:362:18:364:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:370:18:372:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:378:18:380:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:386:18:388:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:387:5:387:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:387:5:387:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:394:18:396:4 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:395:5:395:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:395:5:395:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:402:33:404:3 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:403:4:403:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:403:4:403:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:409:31:411:3 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:410:4:410:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:410:4:410:46 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:418:19:420:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:419:6:419:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:419:6:419:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:425:19:427:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:426:6:426:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:426:6:426:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:432:19:434:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:442:19:444:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:443:6:443:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:443:6:443:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:449:19:451:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:450:6:450:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:450:6:450:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:456:19:458:5 | slice literal | semmle.label | slice literal | -| UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | subpaths #select | UnsafeTLS.go:21:23:21:23 | 0 | UnsafeTLS.go:21:23:21:23 | 0 | UnsafeTLS.go:21:23:21:23 | 0 | Using lowest TLS version for MinVersion. | @@ -159,22 +141,22 @@ subpaths | UnsafeTLS.go:111:16:111:16 | 0 | UnsafeTLS.go:111:16:111:16 | 0 | UnsafeTLS.go:111:16:111:16 | 0 | Using lowest TLS version for MinVersion. | | UnsafeTLS.go:201:17:201:17 | 0 | UnsafeTLS.go:201:17:201:17 | 0 | UnsafeTLS.go:201:17:201:17 | 0 | Using lowest TLS version for MinVersion. | | UnsafeTLS.go:219:17:219:17 | 0 | UnsafeTLS.go:219:17:219:17 | 0 | UnsafeTLS.go:219:17:219:17 | 0 | Using lowest TLS version for MinVersion. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:272:18:274:4 | slice literal | UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:272:18:274:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:280:18:282:4 | slice literal | UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:280:18:282:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:288:18:290:4 | slice literal | UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:288:18:290:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:296:18:298:4 | slice literal | UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:296:18:298:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | -| UnsafeTLS.go:304:18:306:4 | slice literal | UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:304:18:306:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:312:18:314:4 | slice literal | UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:312:18:314:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:329:25:329:94 | call to append | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:329:25:329:94 | call to append | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:336:26:336:58 | call to append | UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:336:26:336:58 | call to append | Use of an insecure cipher suite. | -| UnsafeTLS.go:346:25:346:36 | cipherSuites | UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:346:25:346:36 | cipherSuites | Use of an insecure cipher suite. | -| UnsafeTLS.go:355:25:355:36 | cipherSuites | UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:355:25:355:36 | cipherSuites | Use of an insecure cipher suite. | -| UnsafeTLS.go:362:18:364:4 | slice literal | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:362:18:364:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:432:19:434:5 | slice literal | UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:432:19:434:5 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | -| UnsafeTLS.go:456:19:458:5 | slice literal | UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:456:19:458:5 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:260:5:260:32 | selection of TLS_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:261:5:261:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:262:5:262:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:263:5:263:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:264:5:264:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:259:18:266:4 | slice literal | UnsafeTLS.go:265:5:265:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:259:18:266:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:272:18:274:4 | slice literal | UnsafeTLS.go:273:5:273:32 | selection of TLS_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:272:18:274:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:280:18:282:4 | slice literal | UnsafeTLS.go:281:5:281:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:280:18:282:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:288:18:290:4 | slice literal | UnsafeTLS.go:289:5:289:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | UnsafeTLS.go:288:18:290:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:296:18:298:4 | slice literal | UnsafeTLS.go:297:5:297:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA | UnsafeTLS.go:296:18:298:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:304:18:306:4 | slice literal | UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:304:18:306:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:312:18:314:4 | slice literal | UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:312:18:314:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:329:25:329:94 | call to append | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:329:25:329:94 | call to append | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:336:26:336:58 | call to append | UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | UnsafeTLS.go:336:26:336:58 | call to append | Use of an insecure cipher suite. | +| UnsafeTLS.go:346:25:346:36 | cipherSuites | UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | UnsafeTLS.go:346:25:346:36 | cipherSuites | Use of an insecure cipher suite. | +| UnsafeTLS.go:355:25:355:36 | cipherSuites | UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | UnsafeTLS.go:355:25:355:36 | cipherSuites | Use of an insecure cipher suite. | +| UnsafeTLS.go:362:18:364:4 | slice literal | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:362:18:364:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:432:19:434:5 | slice literal | UnsafeTLS.go:433:6:433:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:432:19:434:5 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:456:19:458:5 | slice literal | UnsafeTLS.go:457:6:457:48 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:456:19:458:5 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | diff --git a/go/ql/test/query-tests/Security/CWE-327/WeakCryptoAlgorithm.expected b/go/ql/test/query-tests/Security/CWE-327/WeakCryptoAlgorithm.expected index 50d09ac532d..a107cd75df0 100644 --- a/go/ql/test/query-tests/Security/CWE-327/WeakCryptoAlgorithm.expected +++ b/go/ql/test/query-tests/Security/CWE-327/WeakCryptoAlgorithm.expected @@ -1,17 +1,17 @@ edges -| Crypto.go:16:9:16:16 | password : slice type | Crypto.go:19:25:19:27 | buf | -| Crypto.go:16:9:16:16 | password : slice type | Crypto.go:22:10:22:12 | buf | -| Crypto.go:16:9:16:16 | password : slice type | Crypto.go:25:16:25:18 | buf | -| Crypto.go:16:9:16:16 | password : slice type | Crypto.go:28:11:28:13 | buf | +| Crypto.go:16:9:16:16 | password | Crypto.go:19:25:19:27 | buf | +| Crypto.go:16:9:16:16 | password | Crypto.go:22:10:22:12 | buf | +| Crypto.go:16:9:16:16 | password | Crypto.go:25:16:25:18 | buf | +| Crypto.go:16:9:16:16 | password | Crypto.go:28:11:28:13 | buf | nodes -| Crypto.go:16:9:16:16 | password : slice type | semmle.label | password : slice type | +| Crypto.go:16:9:16:16 | password | semmle.label | password | | Crypto.go:19:25:19:27 | buf | semmle.label | buf | | Crypto.go:22:10:22:12 | buf | semmle.label | buf | | Crypto.go:25:16:25:18 | buf | semmle.label | buf | | Crypto.go:28:11:28:13 | buf | semmle.label | buf | subpaths #select -| Crypto.go:19:25:19:27 | buf | Crypto.go:16:9:16:16 | password : slice type | Crypto.go:19:25:19:27 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | -| Crypto.go:22:10:22:12 | buf | Crypto.go:16:9:16:16 | password : slice type | Crypto.go:22:10:22:12 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | -| Crypto.go:25:16:25:18 | buf | Crypto.go:16:9:16:16 | password : slice type | Crypto.go:25:16:25:18 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | -| Crypto.go:28:11:28:13 | buf | Crypto.go:16:9:16:16 | password : slice type | Crypto.go:28:11:28:13 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | +| Crypto.go:19:25:19:27 | buf | Crypto.go:16:9:16:16 | password | Crypto.go:19:25:19:27 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | +| Crypto.go:22:10:22:12 | buf | Crypto.go:16:9:16:16 | password | Crypto.go:22:10:22:12 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | +| Crypto.go:25:16:25:18 | buf | Crypto.go:16:9:16:16 | password | Crypto.go:25:16:25:18 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | +| Crypto.go:28:11:28:13 | buf | Crypto.go:16:9:16:16 | password | Crypto.go:28:11:28:13 | buf | $@ is used in a weak cryptographic algorithm. | Crypto.go:16:9:16:16 | password | Sensitive data | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index 2ba310c6ee1..9e767daf186 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -1,16 +1,16 @@ edges -| sample.go:15:24:15:63 | type conversion : string | sample.go:16:9:16:15 | slice expression : slice type | -| sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:15:24:15:63 | type conversion : string | -| sample.go:16:9:16:15 | slice expression : slice type | sample.go:26:25:26:30 | call to Guid | -| sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | -| sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | +| sample.go:15:24:15:63 | type conversion | sample.go:16:9:16:15 | slice expression | +| sample.go:15:49:15:61 | call to Uint32 | sample.go:15:24:15:63 | type conversion | +| sample.go:16:9:16:15 | slice expression | sample.go:26:25:26:30 | call to Guid | +| sample.go:34:12:34:40 | call to New | sample.go:37:25:37:29 | nonce | +| sample.go:34:12:34:40 | call to New | sample.go:37:32:37:36 | nonce | nodes | InsecureRandomness.go:12:18:12:40 | call to Intn | semmle.label | call to Intn | -| sample.go:15:24:15:63 | type conversion : string | semmle.label | type conversion : string | -| sample.go:15:49:15:61 | call to Uint32 : uint32 | semmle.label | call to Uint32 : uint32 | -| sample.go:16:9:16:15 | slice expression : slice type | semmle.label | slice expression : slice type | +| sample.go:15:24:15:63 | type conversion | semmle.label | type conversion | +| sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | +| sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | | sample.go:26:25:26:30 | call to Guid | semmle.label | call to Guid | -| sample.go:34:12:34:40 | call to New : pointer type | semmle.label | call to New : pointer type | +| sample.go:34:12:34:40 | call to New | semmle.label | call to New | | sample.go:37:25:37:29 | nonce | semmle.label | nonce | | sample.go:37:32:37:36 | nonce | semmle.label | nonce | | sample.go:43:17:43:39 | call to Intn | semmle.label | call to Intn | @@ -21,7 +21,7 @@ nodes subpaths #select | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | InsecureRandomness.go:12:18:12:40 | call to Intn | random number | -| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number | -| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | -| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number | +| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number | diff --git a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected index 06cc9c6618e..c21e28717c7 100644 --- a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected +++ b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected @@ -1,61 +1,61 @@ edges -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:50:26:50:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:147:26:147:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:169:26:169:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:191:26:191:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:210:26:210:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:232:26:232:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:249:26:249:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:266:26:266:41 | stateStringConst | -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:282:26:282:41 | stateStringConst | -| ConstantOauth2State.go:22:22:22:28 | "state" : string | ConstantOauth2State.go:65:26:65:39 | stateStringVar | -| ConstantOauth2State.go:80:11:80:25 | call to newFixedState : string | ConstantOauth2State.go:81:26:81:30 | state | -| ConstantOauth2State.go:86:9:86:15 | "state" : string | ConstantOauth2State.go:80:11:80:25 | call to newFixedState : string | -| ConstantOauth2State.go:147:9:147:42 | call to AuthCodeURL : string | ConstantOauth2State.go:148:54:148:56 | url | -| ConstantOauth2State.go:169:9:169:42 | call to AuthCodeURL : string | ConstantOauth2State.go:170:54:170:56 | url | -| ConstantOauth2State.go:191:9:191:42 | call to AuthCodeURL : string | ConstantOauth2State.go:192:54:192:56 | url | -| ConstantOauth2State.go:210:9:210:42 | call to AuthCodeURL : string | ConstantOauth2State.go:211:54:211:56 | url | -| ConstantOauth2State.go:232:9:232:42 | call to AuthCodeURL : string | ConstantOauth2State.go:233:28:233:30 | url | -| ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" : string | ConstantOauth2State.go:249:9:249:12 | conf | -| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" : string | ConstantOauth2State.go:266:9:266:12 | conf | -| ConstantOauth2State.go:272:17:272:21 | "oob" : string | ConstantOauth2State.go:282:9:282:12 | conf | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:50:26:50:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:147:26:147:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:169:26:169:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:191:26:191:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:210:26:210:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:232:26:232:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:249:26:249:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:266:26:266:41 | stateStringConst | +| ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:282:26:282:41 | stateStringConst | +| ConstantOauth2State.go:22:22:22:28 | "state" | ConstantOauth2State.go:65:26:65:39 | stateStringVar | +| ConstantOauth2State.go:80:11:80:25 | call to newFixedState | ConstantOauth2State.go:81:26:81:30 | state | +| ConstantOauth2State.go:86:9:86:15 | "state" | ConstantOauth2State.go:80:11:80:25 | call to newFixedState | +| ConstantOauth2State.go:147:9:147:42 | call to AuthCodeURL | ConstantOauth2State.go:148:54:148:56 | url | +| ConstantOauth2State.go:169:9:169:42 | call to AuthCodeURL | ConstantOauth2State.go:170:54:170:56 | url | +| ConstantOauth2State.go:191:9:191:42 | call to AuthCodeURL | ConstantOauth2State.go:192:54:192:56 | url | +| ConstantOauth2State.go:210:9:210:42 | call to AuthCodeURL | ConstantOauth2State.go:211:54:211:56 | url | +| ConstantOauth2State.go:232:9:232:42 | call to AuthCodeURL | ConstantOauth2State.go:233:28:233:30 | url | +| ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" | ConstantOauth2State.go:249:9:249:12 | conf | +| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" | ConstantOauth2State.go:266:9:266:12 | conf | +| ConstantOauth2State.go:272:17:272:21 | "oob" | ConstantOauth2State.go:282:9:282:12 | conf | nodes -| ConstantOauth2State.go:20:26:20:32 | "state" : string literal | semmle.label | "state" : string literal | -| ConstantOauth2State.go:22:22:22:28 | "state" : string | semmle.label | "state" : string | +| ConstantOauth2State.go:20:26:20:32 | "state" | semmle.label | "state" | +| ConstantOauth2State.go:22:22:22:28 | "state" | semmle.label | "state" | | ConstantOauth2State.go:35:26:35:32 | "state" | semmle.label | "state" | | ConstantOauth2State.go:50:26:50:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:65:26:65:39 | stateStringVar | semmle.label | stateStringVar | -| ConstantOauth2State.go:80:11:80:25 | call to newFixedState : string | semmle.label | call to newFixedState : string | +| ConstantOauth2State.go:80:11:80:25 | call to newFixedState | semmle.label | call to newFixedState | | ConstantOauth2State.go:81:26:81:30 | state | semmle.label | state | -| ConstantOauth2State.go:86:9:86:15 | "state" : string | semmle.label | "state" : string | -| ConstantOauth2State.go:147:9:147:42 | call to AuthCodeURL : string | semmle.label | call to AuthCodeURL : string | +| ConstantOauth2State.go:86:9:86:15 | "state" | semmle.label | "state" | +| ConstantOauth2State.go:147:9:147:42 | call to AuthCodeURL | semmle.label | call to AuthCodeURL | | ConstantOauth2State.go:147:26:147:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:148:54:148:56 | url | semmle.label | url | -| ConstantOauth2State.go:169:9:169:42 | call to AuthCodeURL : string | semmle.label | call to AuthCodeURL : string | +| ConstantOauth2State.go:169:9:169:42 | call to AuthCodeURL | semmle.label | call to AuthCodeURL | | ConstantOauth2State.go:169:26:169:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:170:54:170:56 | url | semmle.label | url | -| ConstantOauth2State.go:191:9:191:42 | call to AuthCodeURL : string | semmle.label | call to AuthCodeURL : string | +| ConstantOauth2State.go:191:9:191:42 | call to AuthCodeURL | semmle.label | call to AuthCodeURL | | ConstantOauth2State.go:191:26:191:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:192:54:192:56 | url | semmle.label | url | -| ConstantOauth2State.go:210:9:210:42 | call to AuthCodeURL : string | semmle.label | call to AuthCodeURL : string | +| ConstantOauth2State.go:210:9:210:42 | call to AuthCodeURL | semmle.label | call to AuthCodeURL | | ConstantOauth2State.go:210:26:210:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:211:54:211:56 | url | semmle.label | url | -| ConstantOauth2State.go:232:9:232:42 | call to AuthCodeURL : string | semmle.label | call to AuthCodeURL : string | +| ConstantOauth2State.go:232:9:232:42 | call to AuthCodeURL | semmle.label | call to AuthCodeURL | | ConstantOauth2State.go:232:26:232:41 | stateStringConst | semmle.label | stateStringConst | | ConstantOauth2State.go:233:28:233:30 | url | semmle.label | url | -| ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" : string | semmle.label | "http://localhost:8080" : string | +| ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" | semmle.label | "http://localhost:8080" | | ConstantOauth2State.go:249:9:249:12 | conf | semmle.label | conf | | ConstantOauth2State.go:249:26:249:41 | stateStringConst | semmle.label | stateStringConst | -| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" : string | semmle.label | "http://localhost:8080" : string | +| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" | semmle.label | "http://localhost:8080" | | ConstantOauth2State.go:266:9:266:12 | conf | semmle.label | conf | | ConstantOauth2State.go:266:26:266:41 | stateStringConst | semmle.label | stateStringConst | -| ConstantOauth2State.go:272:17:272:21 | "oob" : string | semmle.label | "oob" : string | +| ConstantOauth2State.go:272:17:272:21 | "oob" | semmle.label | "oob" | | ConstantOauth2State.go:282:9:282:12 | conf | semmle.label | conf | | ConstantOauth2State.go:282:26:282:41 | stateStringConst | semmle.label | stateStringConst | subpaths #select | ConstantOauth2State.go:35:26:35:32 | "state" | ConstantOauth2State.go:35:26:35:32 | "state" | ConstantOauth2State.go:35:26:35:32 | "state" | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:35:26:35:32 | "state" | state string | -| ConstantOauth2State.go:50:26:50:41 | stateStringConst | ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:50:26:50:41 | stateStringConst | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:20:26:20:32 | "state" | state string | -| ConstantOauth2State.go:65:26:65:39 | stateStringVar | ConstantOauth2State.go:22:22:22:28 | "state" : string | ConstantOauth2State.go:65:26:65:39 | stateStringVar | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:22:22:22:28 | "state" | state string | -| ConstantOauth2State.go:81:26:81:30 | state | ConstantOauth2State.go:86:9:86:15 | "state" : string | ConstantOauth2State.go:81:26:81:30 | state | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:86:9:86:15 | "state" | state string | -| ConstantOauth2State.go:232:26:232:41 | stateStringConst | ConstantOauth2State.go:20:26:20:32 | "state" : string literal | ConstantOauth2State.go:232:26:232:41 | stateStringConst | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:20:26:20:32 | "state" | state string | +| ConstantOauth2State.go:50:26:50:41 | stateStringConst | ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:50:26:50:41 | stateStringConst | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:20:26:20:32 | "state" | state string | +| ConstantOauth2State.go:65:26:65:39 | stateStringVar | ConstantOauth2State.go:22:22:22:28 | "state" | ConstantOauth2State.go:65:26:65:39 | stateStringVar | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:22:22:22:28 | "state" | state string | +| ConstantOauth2State.go:81:26:81:30 | state | ConstantOauth2State.go:86:9:86:15 | "state" | ConstantOauth2State.go:81:26:81:30 | state | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:86:9:86:15 | "state" | state string | +| ConstantOauth2State.go:232:26:232:41 | stateStringConst | ConstantOauth2State.go:20:26:20:32 | "state" | ConstantOauth2State.go:232:26:232:41 | stateStringConst | Using a constant $@ to create oauth2 URLs. | ConstantOauth2State.go:20:26:20:32 | "state" | state string | diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected index e140ce0ce96..df3c6383bc4 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected @@ -1,56 +1,56 @@ edges -| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir : string | BadRedirectCheck.go:5:10:5:14 | redir : string | -| BadRedirectCheck.go:3:18:3:22 | definition of redir : string | BadRedirectCheck.go:5:10:5:14 | redir : string | -| BadRedirectCheck.go:5:10:5:14 | redir : string | main.go:11:25:11:45 | call to sanitizeUrl | -| cves.go:14:23:14:25 | argument corresponding to url : string | cves.go:16:26:16:28 | url | -| cves.go:33:14:33:34 | call to Get : string | cves.go:37:25:37:32 | redirect | -| cves.go:41:14:41:34 | call to Get : string | cves.go:45:25:45:32 | redirect | -| main.go:10:18:10:25 | argument corresponding to redirect : string | main.go:11:37:11:44 | redirect : string | -| main.go:11:37:11:44 | redirect : string | BadRedirectCheck.go:3:18:3:22 | definition of redir : string | -| main.go:11:37:11:44 | redirect : string | main.go:11:25:11:45 | call to sanitizeUrl | -| main.go:32:24:32:26 | argument corresponding to url : string | main.go:34:26:34:28 | url | -| main.go:68:17:68:24 | argument corresponding to redirect : string | main.go:73:9:73:28 | call to Clean : string | -| main.go:68:17:68:24 | definition of redirect : string | main.go:73:9:73:28 | call to Clean : string | -| main.go:73:9:73:28 | call to Clean : string | main.go:77:25:77:39 | call to getTarget1 | -| main.go:76:19:76:21 | argument corresponding to url : string | main.go:77:36:77:38 | url : string | -| main.go:77:36:77:38 | url : string | main.go:68:17:68:24 | definition of redirect : string | -| main.go:77:36:77:38 | url : string | main.go:77:25:77:39 | call to getTarget1 | -| main.go:87:9:87:14 | selection of Path : string | main.go:91:25:91:39 | call to getTarget2 | +| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | BadRedirectCheck.go:5:10:5:14 | redir | +| BadRedirectCheck.go:3:18:3:22 | definition of redir | BadRedirectCheck.go:5:10:5:14 | redir | +| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | +| cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | +| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | +| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | +| main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:37:11:44 | redirect | +| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | +| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | +| main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | +| main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:9:73:28 | call to Clean | +| main.go:68:17:68:24 | definition of redirect | main.go:73:9:73:28 | call to Clean | +| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | +| main.go:76:19:76:21 | argument corresponding to url | main.go:77:36:77:38 | url | +| main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | +| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | +| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | nodes -| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir : string | semmle.label | argument corresponding to redir : string | -| BadRedirectCheck.go:3:18:3:22 | definition of redir : string | semmle.label | definition of redir : string | -| BadRedirectCheck.go:5:10:5:14 | redir : string | semmle.label | redir : string | -| BadRedirectCheck.go:5:10:5:14 | redir : string | semmle.label | redir : string | -| cves.go:14:23:14:25 | argument corresponding to url : string | semmle.label | argument corresponding to url : string | +| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | semmle.label | argument corresponding to redir | +| BadRedirectCheck.go:3:18:3:22 | definition of redir | semmle.label | definition of redir | +| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir | +| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir | +| cves.go:14:23:14:25 | argument corresponding to url | semmle.label | argument corresponding to url | | cves.go:16:26:16:28 | url | semmle.label | url | -| cves.go:33:14:33:34 | call to Get : string | semmle.label | call to Get : string | +| cves.go:33:14:33:34 | call to Get | semmle.label | call to Get | | cves.go:37:25:37:32 | redirect | semmle.label | redirect | -| cves.go:41:14:41:34 | call to Get : string | semmle.label | call to Get : string | +| cves.go:41:14:41:34 | call to Get | semmle.label | call to Get | | cves.go:45:25:45:32 | redirect | semmle.label | redirect | -| main.go:10:18:10:25 | argument corresponding to redirect : string | semmle.label | argument corresponding to redirect : string | +| main.go:10:18:10:25 | argument corresponding to redirect | semmle.label | argument corresponding to redirect | | main.go:11:25:11:45 | call to sanitizeUrl | semmle.label | call to sanitizeUrl | -| main.go:11:37:11:44 | redirect : string | semmle.label | redirect : string | -| main.go:32:24:32:26 | argument corresponding to url : string | semmle.label | argument corresponding to url : string | +| main.go:11:37:11:44 | redirect | semmle.label | redirect | +| main.go:32:24:32:26 | argument corresponding to url | semmle.label | argument corresponding to url | | main.go:34:26:34:28 | url | semmle.label | url | -| main.go:68:17:68:24 | argument corresponding to redirect : string | semmle.label | argument corresponding to redirect : string | -| main.go:68:17:68:24 | definition of redirect : string | semmle.label | definition of redirect : string | -| main.go:73:9:73:28 | call to Clean : string | semmle.label | call to Clean : string | -| main.go:73:9:73:28 | call to Clean : string | semmle.label | call to Clean : string | -| main.go:76:19:76:21 | argument corresponding to url : string | semmle.label | argument corresponding to url : string | +| main.go:68:17:68:24 | argument corresponding to redirect | semmle.label | argument corresponding to redirect | +| main.go:68:17:68:24 | definition of redirect | semmle.label | definition of redirect | +| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean | +| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean | +| main.go:76:19:76:21 | argument corresponding to url | semmle.label | argument corresponding to url | | main.go:77:25:77:39 | call to getTarget1 | semmle.label | call to getTarget1 | -| main.go:77:36:77:38 | url : string | semmle.label | url : string | -| main.go:87:9:87:14 | selection of Path : string | semmle.label | selection of Path : string | +| main.go:77:36:77:38 | url | semmle.label | url | +| main.go:87:9:87:14 | selection of Path | semmle.label | selection of Path | | main.go:91:25:91:39 | call to getTarget2 | semmle.label | call to getTarget2 | subpaths -| main.go:11:37:11:44 | redirect : string | BadRedirectCheck.go:3:18:3:22 | definition of redir : string | BadRedirectCheck.go:5:10:5:14 | redir : string | main.go:11:25:11:45 | call to sanitizeUrl : string | -| main.go:77:36:77:38 | url : string | main.go:68:17:68:24 | definition of redirect : string | main.go:73:9:73:28 | call to Clean : string | main.go:77:25:77:39 | call to getTarget1 : string | +| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | +| main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | #select -| BadRedirectCheck.go:4:23:4:37 | ...==... | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir : string | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | -| BadRedirectCheck.go:4:23:4:37 | ...==... | main.go:10:18:10:25 | argument corresponding to redirect : string | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:10:18:10:25 | argument corresponding to redirect | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | -| cves.go:11:26:11:38 | ...==... | cves.go:14:23:14:25 | argument corresponding to url : string | cves.go:16:26:16:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:14:23:14:25 | argument corresponding to url | this value | cves.go:16:26:16:28 | url | redirect | -| cves.go:34:6:34:37 | call to HasPrefix | cves.go:33:14:33:34 | call to Get : string | cves.go:37:25:37:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:33:14:33:34 | call to Get | this value | cves.go:37:25:37:32 | redirect | redirect | -| cves.go:42:6:42:37 | call to HasPrefix | cves.go:41:14:41:34 | call to Get : string | cves.go:45:25:45:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:41:14:41:34 | call to Get | this value | cves.go:45:25:45:32 | redirect | redirect | -| main.go:25:7:25:38 | call to HasPrefix | main.go:32:24:32:26 | argument corresponding to url : string | main.go:34:26:34:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:32:24:32:26 | argument corresponding to url | this value | main.go:34:26:34:28 | url | redirect | -| main.go:69:5:69:22 | ...!=... | main.go:68:17:68:24 | argument corresponding to redirect : string | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:68:17:68:24 | argument corresponding to redirect | this value | main.go:77:25:77:39 | call to getTarget1 | redirect | -| main.go:69:5:69:22 | ...!=... | main.go:76:19:76:21 | argument corresponding to url : string | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:76:19:76:21 | argument corresponding to url | this value | main.go:77:25:77:39 | call to getTarget1 | redirect | -| main.go:83:5:83:20 | ...!=... | main.go:87:9:87:14 | selection of Path : string | main.go:91:25:91:39 | call to getTarget2 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:87:9:87:14 | selection of Path | this value | main.go:91:25:91:39 | call to getTarget2 | redirect | +| BadRedirectCheck.go:4:23:4:37 | ...==... | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | +| BadRedirectCheck.go:4:23:4:37 | ...==... | main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:10:18:10:25 | argument corresponding to redirect | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect | +| cves.go:11:26:11:38 | ...==... | cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:14:23:14:25 | argument corresponding to url | this value | cves.go:16:26:16:28 | url | redirect | +| cves.go:34:6:34:37 | call to HasPrefix | cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:33:14:33:34 | call to Get | this value | cves.go:37:25:37:32 | redirect | redirect | +| cves.go:42:6:42:37 | call to HasPrefix | cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:41:14:41:34 | call to Get | this value | cves.go:45:25:45:32 | redirect | redirect | +| main.go:25:7:25:38 | call to HasPrefix | main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:32:24:32:26 | argument corresponding to url | this value | main.go:34:26:34:28 | url | redirect | +| main.go:69:5:69:22 | ...!=... | main.go:68:17:68:24 | argument corresponding to redirect | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:68:17:68:24 | argument corresponding to redirect | this value | main.go:77:25:77:39 | call to getTarget1 | redirect | +| main.go:69:5:69:22 | ...!=... | main.go:76:19:76:21 | argument corresponding to url | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:76:19:76:21 | argument corresponding to url | this value | main.go:77:25:77:39 | call to getTarget1 | redirect | +| main.go:83:5:83:20 | ...!=... | main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:87:9:87:14 | selection of Path | this value | main.go:91:25:91:39 | call to getTarget2 | redirect | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index c27f575acc3..f7e2677efef 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -1,132 +1,125 @@ edges -| OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | OpenUrlRedirect.go:10:23:10:42 | call to Get | -| stdlib.go:13:13:13:18 | selection of Form : Values | stdlib.go:15:30:15:35 | target | -| stdlib.go:22:13:22:18 | selection of Form : Values | stdlib.go:24:30:24:35 | target | -| stdlib.go:31:13:31:18 | selection of Form : Values | stdlib.go:35:30:35:39 | ...+... | -| stdlib.go:44:13:44:18 | selection of Form : Values | stdlib.go:46:23:46:28 | target | -| stdlib.go:64:13:64:18 | selection of Form : Values | stdlib.go:67:23:67:40 | ...+... | -| stdlib.go:89:13:89:18 | selection of Form : Values | stdlib.go:92:23:92:28 | target | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | -| stdlib.go:112:4:112:8 | implicit dereference : URL | stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | stdlib.go:112:4:112:8 | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | stdlib.go:112:4:112:8 | implicit dereference : URL | -| stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | stdlib.go:113:24:113:28 | selection of URL : pointer type | -| stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | stdlib.go:113:24:113:28 | selection of URL : pointer type | -| stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | -| stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | -| stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | -| stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | -| stdlib.go:146:13:146:18 | selection of Form : Values | stdlib.go:152:23:152:28 | target | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | -| stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | -| stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | -| stdlib.go:182:13:182:33 | call to FormValue : string | stdlib.go:184:23:184:28 | target | -| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:28 | implicit dereference : URL | -| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:33 | selection of Path | -| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:194:23:194:42 | call to EscapedPath | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:28 | implicit dereference : URL | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:33 | selection of Path | -| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:194:23:194:42 | call to EscapedPath | +| OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | +| stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | +| stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | +| stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | +| stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | +| stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | +| stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:112:4:112:4 | r [pointer, URL] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:112:4:112:4 | r [pointer, URL] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:113:24:113:24 | r [pointer, URL] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:113:24:113:24 | r [pointer, URL] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:112:4:112:8 | selection of URL [pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:112:4:112:8 | selection of URL [pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:4 | r [pointer, URL] | stdlib.go:112:4:112:4 | implicit dereference [URL] | +| stdlib.go:112:4:112:4 | r [pointer, URL] | stdlib.go:112:4:112:4 | implicit dereference [URL] | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL [pointer] | +| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL [pointer] | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:4 | implicit dereference [URL] | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:4 | implicit dereference [URL] | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | selection of URL | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:8 | implicit dereference | +| stdlib.go:113:24:113:24 | implicit dereference [URL] | stdlib.go:113:24:113:28 | selection of URL | +| stdlib.go:113:24:113:24 | implicit dereference [URL] | stdlib.go:113:24:113:28 | selection of URL | +| stdlib.go:113:24:113:24 | r [pointer, URL] | stdlib.go:113:24:113:24 | implicit dereference [URL] | +| stdlib.go:113:24:113:24 | r [pointer, URL] | stdlib.go:113:24:113:24 | implicit dereference [URL] | +| stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | +| stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | +| stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | +| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:35 | call to String | +| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:35 | call to String | +| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | +| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | +| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | nodes -| OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | semmle.label | selection of Form : Values | +| OpenUrlRedirect.go:10:23:10:28 | selection of Form | semmle.label | selection of Form | | OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get | -| stdlib.go:13:13:13:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:13:13:13:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:15:30:15:35 | target | semmle.label | target | -| stdlib.go:22:13:22:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:22:13:22:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:24:30:24:35 | target | semmle.label | target | -| stdlib.go:31:13:31:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:31:13:31:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:35:30:35:39 | ...+... | semmle.label | ...+... | -| stdlib.go:44:13:44:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:44:13:44:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:46:23:46:28 | target | semmle.label | target | -| stdlib.go:64:13:64:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:64:13:64:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:67:23:67:40 | ...+... | semmle.label | ...+... | -| stdlib.go:89:13:89:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:89:13:89:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:92:23:92:28 | target | semmle.label | target | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | semmle.label | definition of r [pointer, URL, pointer] : URL | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] : URL | semmle.label | definition of r [pointer, URL, pointer] : URL | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | semmle.label | definition of r [pointer, URL] : pointer type | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] : pointer type | semmle.label | definition of r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | semmle.label | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] : URL | semmle.label | implicit dereference [URL, pointer] : URL | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | semmle.label | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:4 | implicit dereference [URL] : pointer type | semmle.label | implicit dereference [URL] : pointer type | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | semmle.label | r [pointer, URL, pointer] : URL | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] : URL | semmle.label | r [pointer, URL, pointer] : URL | -| stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | semmle.label | r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:4 | r [pointer, URL] : pointer type | semmle.label | r [pointer, URL] : pointer type | -| stdlib.go:112:4:112:8 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| stdlib.go:112:4:112:8 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | semmle.label | selection of URL [pointer] : URL | -| stdlib.go:112:4:112:8 | selection of URL [pointer] : URL | semmle.label | selection of URL [pointer] : URL | -| stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | semmle.label | implicit dereference [URL] : pointer type | -| stdlib.go:113:24:113:24 | implicit dereference [URL] : pointer type | semmle.label | implicit dereference [URL] : pointer type | -| stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | semmle.label | r [pointer, URL] : pointer type | -| stdlib.go:113:24:113:24 | r [pointer, URL] : pointer type | semmle.label | r [pointer, URL] : pointer type | -| stdlib.go:113:24:113:28 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:113:24:113:28 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | semmle.label | definition of r [pointer, URL] | +| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | semmle.label | definition of r [pointer, URL] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | semmle.label | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | semmle.label | implicit dereference [URL, pointer] | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:112:4:112:4 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | +| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | +| stdlib.go:112:4:112:4 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:112:4:112:4 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:112:4:112:8 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:112:4:112:8 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:112:4:112:8 | selection of URL | semmle.label | selection of URL | +| stdlib.go:112:4:112:8 | selection of URL | semmle.label | selection of URL | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | semmle.label | selection of URL [pointer] | +| stdlib.go:112:4:112:8 | selection of URL [pointer] | semmle.label | selection of URL [pointer] | +| stdlib.go:113:24:113:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:113:24:113:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:113:24:113:24 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:113:24:113:24 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:113:24:113:28 | selection of URL | semmle.label | selection of URL | +| stdlib.go:113:24:113:28 | selection of URL | semmle.label | selection of URL | | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | -| stdlib.go:146:13:146:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:146:13:146:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:152:23:152:28 | target | semmle.label | target | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:159:11:159:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:159:11:159:15 | selection of URL | semmle.label | selection of URL | +| stdlib.go:159:11:159:15 | selection of URL | semmle.label | selection of URL | | stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | | stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | | stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | | stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | -| stdlib.go:173:35:173:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:173:35:173:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:182:13:182:33 | call to FormValue : string | semmle.label | call to FormValue : string | +| stdlib.go:173:35:173:39 | selection of URL | semmle.label | selection of URL | +| stdlib.go:173:35:173:39 | selection of URL | semmle.label | selection of URL | +| stdlib.go:182:13:182:33 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:184:23:184:28 | target | semmle.label | target | -| stdlib.go:190:36:190:56 | call to FormValue : string | semmle.label | call to FormValue : string | -| stdlib.go:192:23:192:28 | implicit dereference : URL | semmle.label | implicit dereference : URL | +| stdlib.go:190:36:190:56 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:192:23:192:33 | selection of Path | semmle.label | selection of Path | | stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | subpaths #select -| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value | -| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form : Values | stdlib.go:15:30:15:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | -| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form : Values | stdlib.go:24:30:24:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value | -| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form : Values | stdlib.go:35:30:35:39 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value | -| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form : Values | stdlib.go:46:23:46:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | -| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form : Values | stdlib.go:67:23:67:40 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | -| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form : Values | stdlib.go:92:23:92:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | -| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form : Values | stdlib.go:152:23:152:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | -| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue : string | stdlib.go:184:23:184:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | -| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:33 | selection of Path | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | -| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:194:23:194:42 | call to EscapedPath | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value | +| stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | +| stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | Untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value | +| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value | +| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | +| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | Untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | +| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | +| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | +| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | Untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | +| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | Untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index 2061b253cdc..797d06f208e 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -1,44 +1,44 @@ edges -| EmailBad.go:9:10:9:17 | selection of Header : Header | EmailBad.go:12:56:12:67 | type conversion | -| main.go:29:21:29:31 | call to Referer : string | main.go:31:57:31:78 | type conversion | -| main.go:37:21:37:31 | call to Referer : string | main.go:40:3:40:7 | definition of write | -| main.go:46:21:46:31 | call to Referer : string | main.go:52:46:52:59 | untrustedInput | -| main.go:46:21:46:31 | call to Referer : string | main.go:53:52:53:65 | untrustedInput | -| main.go:58:21:58:31 | call to Referer : string | main.go:63:16:63:22 | content | -| main.go:68:21:68:31 | call to Referer : string | main.go:76:50:76:56 | content | -| main.go:68:21:68:31 | call to Referer : string | main.go:76:59:76:65 | content | -| main.go:68:21:68:31 | call to Referer : string | main.go:77:16:77:22 | content | -| main.go:82:21:82:31 | call to Referer : string | main.go:89:37:89:50 | untrustedInput | -| main.go:82:21:82:31 | call to Referer : string | main.go:93:16:93:23 | content2 | +| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | +| main.go:29:21:29:31 | call to Referer | main.go:31:57:31:78 | type conversion | +| main.go:37:21:37:31 | call to Referer | main.go:40:3:40:7 | definition of write | +| main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | +| main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | +| main.go:58:21:58:31 | call to Referer | main.go:63:16:63:22 | content | +| main.go:68:21:68:31 | call to Referer | main.go:76:50:76:56 | content | +| main.go:68:21:68:31 | call to Referer | main.go:76:59:76:65 | content | +| main.go:68:21:68:31 | call to Referer | main.go:77:16:77:22 | content | +| main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | +| main.go:82:21:82:31 | call to Referer | main.go:93:16:93:23 | content2 | nodes -| EmailBad.go:9:10:9:17 | selection of Header : Header | semmle.label | selection of Header : Header | +| EmailBad.go:9:10:9:17 | selection of Header | semmle.label | selection of Header | | EmailBad.go:12:56:12:67 | type conversion | semmle.label | type conversion | -| main.go:29:21:29:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:29:21:29:31 | call to Referer | semmle.label | call to Referer | | main.go:31:57:31:78 | type conversion | semmle.label | type conversion | -| main.go:37:21:37:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:37:21:37:31 | call to Referer | semmle.label | call to Referer | | main.go:40:3:40:7 | definition of write | semmle.label | definition of write | -| main.go:46:21:46:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:46:21:46:31 | call to Referer | semmle.label | call to Referer | | main.go:52:46:52:59 | untrustedInput | semmle.label | untrustedInput | | main.go:53:52:53:65 | untrustedInput | semmle.label | untrustedInput | -| main.go:58:21:58:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:58:21:58:31 | call to Referer | semmle.label | call to Referer | | main.go:63:16:63:22 | content | semmle.label | content | -| main.go:68:21:68:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:68:21:68:31 | call to Referer | semmle.label | call to Referer | | main.go:76:50:76:56 | content | semmle.label | content | | main.go:76:59:76:65 | content | semmle.label | content | | main.go:77:16:77:22 | content | semmle.label | content | -| main.go:82:21:82:31 | call to Referer : string | semmle.label | call to Referer : string | +| main.go:82:21:82:31 | call to Referer | semmle.label | call to Referer | | main.go:89:37:89:50 | untrustedInput | semmle.label | untrustedInput | | main.go:93:16:93:23 | content2 | semmle.label | content2 | subpaths #select -| EmailBad.go:12:56:12:67 | type conversion | EmailBad.go:9:10:9:17 | selection of Header : Header | EmailBad.go:12:56:12:67 | type conversion | Email content may contain $@. | EmailBad.go:9:10:9:17 | selection of Header | untrusted input | -| main.go:31:57:31:78 | type conversion | main.go:29:21:29:31 | call to Referer : string | main.go:31:57:31:78 | type conversion | Email content may contain $@. | main.go:29:21:29:31 | call to Referer | untrusted input | -| main.go:40:3:40:7 | definition of write | main.go:37:21:37:31 | call to Referer : string | main.go:40:3:40:7 | definition of write | Email content may contain $@. | main.go:37:21:37:31 | call to Referer | untrusted input | -| main.go:52:46:52:59 | untrustedInput | main.go:46:21:46:31 | call to Referer : string | main.go:52:46:52:59 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | -| main.go:53:52:53:65 | untrustedInput | main.go:46:21:46:31 | call to Referer : string | main.go:53:52:53:65 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | -| main.go:63:16:63:22 | content | main.go:58:21:58:31 | call to Referer : string | main.go:63:16:63:22 | content | Email content may contain $@. | main.go:58:21:58:31 | call to Referer | untrusted input | -| main.go:76:50:76:56 | content | main.go:68:21:68:31 | call to Referer : string | main.go:76:50:76:56 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:76:59:76:65 | content | main.go:68:21:68:31 | call to Referer : string | main.go:76:59:76:65 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:77:16:77:22 | content | main.go:68:21:68:31 | call to Referer : string | main.go:77:16:77:22 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:89:37:89:50 | untrustedInput | main.go:82:21:82:31 | call to Referer : string | main.go:89:37:89:50 | untrustedInput | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | -| main.go:93:16:93:23 | content2 | main.go:82:21:82:31 | call to Referer : string | main.go:93:16:93:23 | content2 | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | +| EmailBad.go:12:56:12:67 | type conversion | EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | Email content may contain $@. | EmailBad.go:9:10:9:17 | selection of Header | untrusted input | +| main.go:31:57:31:78 | type conversion | main.go:29:21:29:31 | call to Referer | main.go:31:57:31:78 | type conversion | Email content may contain $@. | main.go:29:21:29:31 | call to Referer | untrusted input | +| main.go:40:3:40:7 | definition of write | main.go:37:21:37:31 | call to Referer | main.go:40:3:40:7 | definition of write | Email content may contain $@. | main.go:37:21:37:31 | call to Referer | untrusted input | +| main.go:52:46:52:59 | untrustedInput | main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | +| main.go:53:52:53:65 | untrustedInput | main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | +| main.go:63:16:63:22 | content | main.go:58:21:58:31 | call to Referer | main.go:63:16:63:22 | content | Email content may contain $@. | main.go:58:21:58:31 | call to Referer | untrusted input | +| main.go:76:50:76:56 | content | main.go:68:21:68:31 | call to Referer | main.go:76:50:76:56 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | +| main.go:76:59:76:65 | content | main.go:68:21:68:31 | call to Referer | main.go:76:59:76:65 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | +| main.go:77:16:77:22 | content | main.go:68:21:68:31 | call to Referer | main.go:77:16:77:22 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | +| main.go:89:37:89:50 | untrustedInput | main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | +| main.go:93:16:93:23 | content2 | main.go:82:21:82:31 | call to Referer | main.go:93:16:93:23 | content2 | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | diff --git a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected index 081b1a2cdba..a391fe96b64 100644 --- a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected @@ -1,57 +1,57 @@ edges -| XPathInjection.go:13:14:13:19 | selection of Form : Values | XPathInjection.go:16:29:16:91 | ...+... | -| tst.go:32:14:32:19 | selection of Form : Values | tst.go:35:23:35:85 | ...+... | -| tst.go:32:14:32:19 | selection of Form : Values | tst.go:38:24:38:86 | ...+... | -| tst.go:32:14:32:19 | selection of Form : Values | tst.go:41:24:41:82 | ...+... | -| tst.go:46:14:46:19 | selection of Form : Values | tst.go:49:26:49:84 | ...+... | -| tst.go:46:14:46:19 | selection of Form : Values | tst.go:52:29:52:87 | ...+... | -| tst.go:46:14:46:19 | selection of Form : Values | tst.go:55:33:55:91 | ...+... | -| tst.go:46:14:46:19 | selection of Form : Values | tst.go:58:30:58:88 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:66:25:66:83 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:69:28:69:86 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:72:25:72:83 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:75:34:75:92 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:78:32:78:90 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:81:29:81:87 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:84:23:84:85 | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | tst.go:87:22:87:84 | ...+... | -| tst.go:92:14:92:19 | selection of Form : Values | tst.go:95:26:95:84 | ...+... | -| tst.go:92:14:92:19 | selection of Form : Values | tst.go:98:29:98:87 | ...+... | -| tst.go:92:14:92:19 | selection of Form : Values | tst.go:101:33:101:91 | ...+... | -| tst.go:92:14:92:19 | selection of Form : Values | tst.go:104:30:104:88 | ...+... | -| tst.go:109:14:109:19 | selection of Form : Values | tst.go:112:25:112:87 | ...+... | -| tst.go:109:14:109:19 | selection of Form : Values | tst.go:115:26:115:88 | ...+... | -| tst.go:120:14:120:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | -| tst.go:120:14:120:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | -| tst.go:120:14:120:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | -| tst.go:121:14:121:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | -| tst.go:121:14:121:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | -| tst.go:121:14:121:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | -| tst.go:138:14:138:19 | selection of Form : Values | tst.go:141:27:141:89 | ...+... | -| tst.go:138:14:138:19 | selection of Form : Values | tst.go:144:28:144:90 | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | -| tst.go:150:14:150:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | -| tst.go:150:14:150:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | -| tst.go:150:14:150:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | -| tst.go:150:14:150:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | -| tst.go:150:14:150:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | +| XPathInjection.go:13:14:13:19 | selection of Form | XPathInjection.go:16:29:16:91 | ...+... | +| tst.go:32:14:32:19 | selection of Form | tst.go:35:23:35:85 | ...+... | +| tst.go:32:14:32:19 | selection of Form | tst.go:38:24:38:86 | ...+... | +| tst.go:32:14:32:19 | selection of Form | tst.go:41:24:41:82 | ...+... | +| tst.go:46:14:46:19 | selection of Form | tst.go:49:26:49:84 | ...+... | +| tst.go:46:14:46:19 | selection of Form | tst.go:52:29:52:87 | ...+... | +| tst.go:46:14:46:19 | selection of Form | tst.go:55:33:55:91 | ...+... | +| tst.go:46:14:46:19 | selection of Form | tst.go:58:30:58:88 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:66:25:66:83 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:69:28:69:86 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:72:25:72:83 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:75:34:75:92 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:78:32:78:90 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:81:29:81:87 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:84:23:84:85 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:87:22:87:84 | ...+... | +| tst.go:92:14:92:19 | selection of Form | tst.go:95:26:95:84 | ...+... | +| tst.go:92:14:92:19 | selection of Form | tst.go:98:29:98:87 | ...+... | +| tst.go:92:14:92:19 | selection of Form | tst.go:101:33:101:91 | ...+... | +| tst.go:92:14:92:19 | selection of Form | tst.go:104:30:104:88 | ...+... | +| tst.go:109:14:109:19 | selection of Form | tst.go:112:25:112:87 | ...+... | +| tst.go:109:14:109:19 | selection of Form | tst.go:115:26:115:88 | ...+... | +| tst.go:120:14:120:19 | selection of Form | tst.go:124:23:124:126 | ...+... | +| tst.go:120:14:120:19 | selection of Form | tst.go:127:24:127:127 | ...+... | +| tst.go:120:14:120:19 | selection of Form | tst.go:130:27:130:122 | ...+... | +| tst.go:121:14:121:19 | selection of Form | tst.go:124:23:124:126 | ...+... | +| tst.go:121:14:121:19 | selection of Form | tst.go:127:24:127:127 | ...+... | +| tst.go:121:14:121:19 | selection of Form | tst.go:130:27:130:122 | ...+... | +| tst.go:138:14:138:19 | selection of Form | tst.go:141:27:141:89 | ...+... | +| tst.go:138:14:138:19 | selection of Form | tst.go:144:28:144:90 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:153:33:153:136 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:156:18:156:121 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:162:31:162:126 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:171:21:171:116 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:180:27:180:122 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:153:33:153:136 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:156:18:156:121 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:162:31:162:126 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:171:21:171:116 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:180:27:180:122 | ...+... | nodes -| XPathInjection.go:13:14:13:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| XPathInjection.go:13:14:13:19 | selection of Form | semmle.label | selection of Form | | XPathInjection.go:16:29:16:91 | ...+... | semmle.label | ...+... | -| tst.go:32:14:32:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:32:14:32:19 | selection of Form | semmle.label | selection of Form | | tst.go:35:23:35:85 | ...+... | semmle.label | ...+... | | tst.go:38:24:38:86 | ...+... | semmle.label | ...+... | | tst.go:41:24:41:82 | ...+... | semmle.label | ...+... | -| tst.go:46:14:46:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:46:14:46:19 | selection of Form | semmle.label | selection of Form | | tst.go:49:26:49:84 | ...+... | semmle.label | ...+... | | tst.go:52:29:52:87 | ...+... | semmle.label | ...+... | | tst.go:55:33:55:91 | ...+... | semmle.label | ...+... | | tst.go:58:30:58:88 | ...+... | semmle.label | ...+... | -| tst.go:63:14:63:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:63:14:63:19 | selection of Form | semmle.label | selection of Form | | tst.go:66:25:66:83 | ...+... | semmle.label | ...+... | | tst.go:69:28:69:86 | ...+... | semmle.label | ...+... | | tst.go:72:25:72:83 | ...+... | semmle.label | ...+... | @@ -60,24 +60,24 @@ nodes | tst.go:81:29:81:87 | ...+... | semmle.label | ...+... | | tst.go:84:23:84:85 | ...+... | semmle.label | ...+... | | tst.go:87:22:87:84 | ...+... | semmle.label | ...+... | -| tst.go:92:14:92:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:92:14:92:19 | selection of Form | semmle.label | selection of Form | | tst.go:95:26:95:84 | ...+... | semmle.label | ...+... | | tst.go:98:29:98:87 | ...+... | semmle.label | ...+... | | tst.go:101:33:101:91 | ...+... | semmle.label | ...+... | | tst.go:104:30:104:88 | ...+... | semmle.label | ...+... | -| tst.go:109:14:109:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:109:14:109:19 | selection of Form | semmle.label | selection of Form | | tst.go:112:25:112:87 | ...+... | semmle.label | ...+... | | tst.go:115:26:115:88 | ...+... | semmle.label | ...+... | -| tst.go:120:14:120:19 | selection of Form : Values | semmle.label | selection of Form : Values | -| tst.go:121:14:121:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:120:14:120:19 | selection of Form | semmle.label | selection of Form | +| tst.go:121:14:121:19 | selection of Form | semmle.label | selection of Form | | tst.go:124:23:124:126 | ...+... | semmle.label | ...+... | | tst.go:127:24:127:127 | ...+... | semmle.label | ...+... | | tst.go:130:27:130:122 | ...+... | semmle.label | ...+... | -| tst.go:138:14:138:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:138:14:138:19 | selection of Form | semmle.label | selection of Form | | tst.go:141:27:141:89 | ...+... | semmle.label | ...+... | | tst.go:144:28:144:90 | ...+... | semmle.label | ...+... | -| tst.go:149:14:149:19 | selection of Form : Values | semmle.label | selection of Form : Values | -| tst.go:150:14:150:19 | selection of Form : Values | semmle.label | selection of Form : Values | +| tst.go:149:14:149:19 | selection of Form | semmle.label | selection of Form | +| tst.go:150:14:150:19 | selection of Form | semmle.label | selection of Form | | tst.go:153:33:153:136 | ...+... | semmle.label | ...+... | | tst.go:156:18:156:121 | ...+... | semmle.label | ...+... | | tst.go:162:31:162:126 | ...+... | semmle.label | ...+... | @@ -85,43 +85,43 @@ nodes | tst.go:180:27:180:122 | ...+... | semmle.label | ...+... | subpaths #select -| XPathInjection.go:16:29:16:91 | ...+... | XPathInjection.go:13:14:13:19 | selection of Form : Values | XPathInjection.go:16:29:16:91 | ...+... | XPath expression depends on a $@. | XPathInjection.go:13:14:13:19 | selection of Form | user-provided value | -| tst.go:35:23:35:85 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:35:23:35:85 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | -| tst.go:38:24:38:86 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:38:24:38:86 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | -| tst.go:41:24:41:82 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:41:24:41:82 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | -| tst.go:49:26:49:84 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:49:26:49:84 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | -| tst.go:52:29:52:87 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:52:29:52:87 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | -| tst.go:55:33:55:91 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:55:33:55:91 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | -| tst.go:58:30:58:88 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:58:30:58:88 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | -| tst.go:66:25:66:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:66:25:66:83 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:69:28:69:86 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:69:28:69:86 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:72:25:72:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:72:25:72:83 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:75:34:75:92 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:75:34:75:92 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:78:32:78:90 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:78:32:78:90 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:81:29:81:87 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:81:29:81:87 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:84:23:84:85 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:84:23:84:85 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:87:22:87:84 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:87:22:87:84 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | -| tst.go:95:26:95:84 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:95:26:95:84 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | -| tst.go:98:29:98:87 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:98:29:98:87 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | -| tst.go:101:33:101:91 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:101:33:101:91 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | -| tst.go:104:30:104:88 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:104:30:104:88 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | -| tst.go:112:25:112:87 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:112:25:112:87 | ...+... | XPath expression depends on a $@. | tst.go:109:14:109:19 | selection of Form | user-provided value | -| tst.go:115:26:115:88 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:115:26:115:88 | ...+... | XPath expression depends on a $@. | tst.go:109:14:109:19 | selection of Form | user-provided value | -| tst.go:124:23:124:126 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | -| tst.go:124:23:124:126 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | -| tst.go:127:24:127:127 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | -| tst.go:127:24:127:127 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | -| tst.go:130:27:130:122 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | -| tst.go:130:27:130:122 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | -| tst.go:141:27:141:89 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:141:27:141:89 | ...+... | XPath expression depends on a $@. | tst.go:138:14:138:19 | selection of Form | user-provided value | -| tst.go:144:28:144:90 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:144:28:144:90 | ...+... | XPath expression depends on a $@. | tst.go:138:14:138:19 | selection of Form | user-provided value | -| tst.go:153:33:153:136 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | -| tst.go:153:33:153:136 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | -| tst.go:156:18:156:121 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | -| tst.go:156:18:156:121 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | -| tst.go:162:31:162:126 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | -| tst.go:162:31:162:126 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | -| tst.go:171:21:171:116 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | -| tst.go:171:21:171:116 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | -| tst.go:180:27:180:122 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | -| tst.go:180:27:180:122 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | +| XPathInjection.go:16:29:16:91 | ...+... | XPathInjection.go:13:14:13:19 | selection of Form | XPathInjection.go:16:29:16:91 | ...+... | XPath expression depends on a $@. | XPathInjection.go:13:14:13:19 | selection of Form | user-provided value | +| tst.go:35:23:35:85 | ...+... | tst.go:32:14:32:19 | selection of Form | tst.go:35:23:35:85 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | +| tst.go:38:24:38:86 | ...+... | tst.go:32:14:32:19 | selection of Form | tst.go:38:24:38:86 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | +| tst.go:41:24:41:82 | ...+... | tst.go:32:14:32:19 | selection of Form | tst.go:41:24:41:82 | ...+... | XPath expression depends on a $@. | tst.go:32:14:32:19 | selection of Form | user-provided value | +| tst.go:49:26:49:84 | ...+... | tst.go:46:14:46:19 | selection of Form | tst.go:49:26:49:84 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | +| tst.go:52:29:52:87 | ...+... | tst.go:46:14:46:19 | selection of Form | tst.go:52:29:52:87 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | +| tst.go:55:33:55:91 | ...+... | tst.go:46:14:46:19 | selection of Form | tst.go:55:33:55:91 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | +| tst.go:58:30:58:88 | ...+... | tst.go:46:14:46:19 | selection of Form | tst.go:58:30:58:88 | ...+... | XPath expression depends on a $@. | tst.go:46:14:46:19 | selection of Form | user-provided value | +| tst.go:66:25:66:83 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:66:25:66:83 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:69:28:69:86 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:69:28:69:86 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:72:25:72:83 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:72:25:72:83 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:75:34:75:92 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:75:34:75:92 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:78:32:78:90 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:78:32:78:90 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:81:29:81:87 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:81:29:81:87 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:84:23:84:85 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:84:23:84:85 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:87:22:87:84 | ...+... | tst.go:63:14:63:19 | selection of Form | tst.go:87:22:87:84 | ...+... | XPath expression depends on a $@. | tst.go:63:14:63:19 | selection of Form | user-provided value | +| tst.go:95:26:95:84 | ...+... | tst.go:92:14:92:19 | selection of Form | tst.go:95:26:95:84 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | +| tst.go:98:29:98:87 | ...+... | tst.go:92:14:92:19 | selection of Form | tst.go:98:29:98:87 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | +| tst.go:101:33:101:91 | ...+... | tst.go:92:14:92:19 | selection of Form | tst.go:101:33:101:91 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | +| tst.go:104:30:104:88 | ...+... | tst.go:92:14:92:19 | selection of Form | tst.go:104:30:104:88 | ...+... | XPath expression depends on a $@. | tst.go:92:14:92:19 | selection of Form | user-provided value | +| tst.go:112:25:112:87 | ...+... | tst.go:109:14:109:19 | selection of Form | tst.go:112:25:112:87 | ...+... | XPath expression depends on a $@. | tst.go:109:14:109:19 | selection of Form | user-provided value | +| tst.go:115:26:115:88 | ...+... | tst.go:109:14:109:19 | selection of Form | tst.go:115:26:115:88 | ...+... | XPath expression depends on a $@. | tst.go:109:14:109:19 | selection of Form | user-provided value | +| tst.go:124:23:124:126 | ...+... | tst.go:120:14:120:19 | selection of Form | tst.go:124:23:124:126 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | +| tst.go:124:23:124:126 | ...+... | tst.go:121:14:121:19 | selection of Form | tst.go:124:23:124:126 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | +| tst.go:127:24:127:127 | ...+... | tst.go:120:14:120:19 | selection of Form | tst.go:127:24:127:127 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | +| tst.go:127:24:127:127 | ...+... | tst.go:121:14:121:19 | selection of Form | tst.go:127:24:127:127 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | +| tst.go:130:27:130:122 | ...+... | tst.go:120:14:120:19 | selection of Form | tst.go:130:27:130:122 | ...+... | XPath expression depends on a $@. | tst.go:120:14:120:19 | selection of Form | user-provided value | +| tst.go:130:27:130:122 | ...+... | tst.go:121:14:121:19 | selection of Form | tst.go:130:27:130:122 | ...+... | XPath expression depends on a $@. | tst.go:121:14:121:19 | selection of Form | user-provided value | +| tst.go:141:27:141:89 | ...+... | tst.go:138:14:138:19 | selection of Form | tst.go:141:27:141:89 | ...+... | XPath expression depends on a $@. | tst.go:138:14:138:19 | selection of Form | user-provided value | +| tst.go:144:28:144:90 | ...+... | tst.go:138:14:138:19 | selection of Form | tst.go:144:28:144:90 | ...+... | XPath expression depends on a $@. | tst.go:138:14:138:19 | selection of Form | user-provided value | +| tst.go:153:33:153:136 | ...+... | tst.go:149:14:149:19 | selection of Form | tst.go:153:33:153:136 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | +| tst.go:153:33:153:136 | ...+... | tst.go:150:14:150:19 | selection of Form | tst.go:153:33:153:136 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | +| tst.go:156:18:156:121 | ...+... | tst.go:149:14:149:19 | selection of Form | tst.go:156:18:156:121 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | +| tst.go:156:18:156:121 | ...+... | tst.go:150:14:150:19 | selection of Form | tst.go:156:18:156:121 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | +| tst.go:162:31:162:126 | ...+... | tst.go:149:14:149:19 | selection of Form | tst.go:162:31:162:126 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | +| tst.go:162:31:162:126 | ...+... | tst.go:150:14:150:19 | selection of Form | tst.go:162:31:162:126 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | +| tst.go:171:21:171:116 | ...+... | tst.go:149:14:149:19 | selection of Form | tst.go:171:21:171:116 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | +| tst.go:171:21:171:116 | ...+... | tst.go:150:14:150:19 | selection of Form | tst.go:171:21:171:116 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | +| tst.go:180:27:180:122 | ...+... | tst.go:149:14:149:19 | selection of Form | tst.go:180:27:180:122 | ...+... | XPath expression depends on a $@. | tst.go:149:14:149:19 | selection of Form | user-provided value | +| tst.go:180:27:180:122 | ...+... | tst.go:150:14:150:19 | selection of Form | tst.go:180:27:180:122 | ...+... | XPath expression depends on a $@. | tst.go:150:14:150:19 | selection of Form | user-provided value | diff --git a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 7751054abbd..d6bb8bbf7af 100644 --- a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -1,75 +1,75 @@ edges -| RequestForgery.go:8:12:8:34 | call to FormValue : string | RequestForgery.go:11:24:11:65 | ...+... | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:14:11:14:17 | tainted | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:18:12:18:18 | tainted | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:21:34:21:40 | tainted | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:24:66:24:72 | tainted | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:27:11:27:29 | ...+... | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:29:11:29:40 | ...+... | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:36:2:36:2 | implicit dereference : URL | -| tst.go:10:13:10:35 | call to FormValue : string | tst.go:37:11:37:20 | call to String | -| tst.go:35:2:35:2 | definition of u [pointer] : URL | tst.go:36:2:36:2 | u [pointer] : URL | -| tst.go:36:2:36:2 | implicit dereference : URL | tst.go:35:2:35:2 | definition of u [pointer] : URL | -| tst.go:36:2:36:2 | implicit dereference : URL | tst.go:36:2:36:2 | implicit dereference : URL | -| tst.go:36:2:36:2 | implicit dereference : URL | tst.go:37:11:37:20 | call to String | -| tst.go:36:2:36:2 | u [pointer] : URL | tst.go:36:2:36:2 | implicit dereference : URL | -| websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | -| websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | -| websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | -| websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | -| websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | -| websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | -| websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | -| websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | -| websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | +| RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | +| tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | +| tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | +| tst.go:10:13:10:35 | call to FormValue | tst.go:21:34:21:40 | tainted | +| tst.go:10:13:10:35 | call to FormValue | tst.go:24:66:24:72 | tainted | +| tst.go:10:13:10:35 | call to FormValue | tst.go:27:11:27:29 | ...+... | +| tst.go:10:13:10:35 | call to FormValue | tst.go:29:11:29:40 | ...+... | +| tst.go:10:13:10:35 | call to FormValue | tst.go:36:2:36:2 | implicit dereference | +| tst.go:10:13:10:35 | call to FormValue | tst.go:37:11:37:20 | call to String | +| tst.go:35:2:35:2 | definition of u [pointer] | tst.go:36:2:36:2 | u [pointer] | +| tst.go:36:2:36:2 | implicit dereference | tst.go:35:2:35:2 | definition of u [pointer] | +| tst.go:36:2:36:2 | implicit dereference | tst.go:36:2:36:2 | implicit dereference | +| tst.go:36:2:36:2 | implicit dereference | tst.go:37:11:37:20 | call to String | +| tst.go:36:2:36:2 | u [pointer] | tst.go:36:2:36:2 | implicit dereference | +| websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | +| websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | +| websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | +| websocket.go:107:21:107:31 | call to Referer | websocket.go:110:15:110:28 | untrustedInput | +| websocket.go:126:21:126:31 | call to Referer | websocket.go:129:38:129:51 | untrustedInput | +| websocket.go:154:21:154:31 | call to Referer | websocket.go:155:31:155:44 | untrustedInput | +| websocket.go:160:21:160:31 | call to Referer | websocket.go:162:31:162:44 | untrustedInput | +| websocket.go:195:21:195:31 | call to Referer | websocket.go:197:18:197:31 | untrustedInput | +| websocket.go:202:21:202:31 | call to Referer | websocket.go:204:11:204:24 | untrustedInput | nodes -| RequestForgery.go:8:12:8:34 | call to FormValue : string | semmle.label | call to FormValue : string | +| RequestForgery.go:8:12:8:34 | call to FormValue | semmle.label | call to FormValue | | RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... | -| tst.go:10:13:10:35 | call to FormValue : string | semmle.label | call to FormValue : string | +| tst.go:10:13:10:35 | call to FormValue | semmle.label | call to FormValue | | tst.go:14:11:14:17 | tainted | semmle.label | tainted | | tst.go:18:12:18:18 | tainted | semmle.label | tainted | | tst.go:21:34:21:40 | tainted | semmle.label | tainted | | tst.go:24:66:24:72 | tainted | semmle.label | tainted | | tst.go:27:11:27:29 | ...+... | semmle.label | ...+... | | tst.go:29:11:29:40 | ...+... | semmle.label | ...+... | -| tst.go:35:2:35:2 | definition of u [pointer] : URL | semmle.label | definition of u [pointer] : URL | -| tst.go:36:2:36:2 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| tst.go:36:2:36:2 | u [pointer] : URL | semmle.label | u [pointer] : URL | +| tst.go:35:2:35:2 | definition of u [pointer] | semmle.label | definition of u [pointer] | +| tst.go:36:2:36:2 | implicit dereference | semmle.label | implicit dereference | +| tst.go:36:2:36:2 | u [pointer] | semmle.label | u [pointer] | | tst.go:37:11:37:20 | call to String | semmle.label | call to String | -| websocket.go:60:21:60:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:60:21:60:31 | call to Referer | semmle.label | call to Referer | | websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:74:21:74:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:74:21:74:31 | call to Referer | semmle.label | call to Referer | | websocket.go:78:36:78:49 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:88:21:88:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:88:21:88:31 | call to Referer | semmle.label | call to Referer | | websocket.go:91:31:91:44 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:107:21:107:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:107:21:107:31 | call to Referer | semmle.label | call to Referer | | websocket.go:110:15:110:28 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:126:21:126:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:126:21:126:31 | call to Referer | semmle.label | call to Referer | | websocket.go:129:38:129:51 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:154:21:154:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:154:21:154:31 | call to Referer | semmle.label | call to Referer | | websocket.go:155:31:155:44 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:160:21:160:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:160:21:160:31 | call to Referer | semmle.label | call to Referer | | websocket.go:162:31:162:44 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:195:21:195:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:195:21:195:31 | call to Referer | semmle.label | call to Referer | | websocket.go:197:18:197:31 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:202:21:202:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:202:21:202:31 | call to Referer | semmle.label | call to Referer | | websocket.go:204:11:204:24 | untrustedInput | semmle.label | untrustedInput | subpaths #select -| RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue : string | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on a $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue : string | user-provided value | -| tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:14:11:14:17 | tainted | The $@ of this request depends on a $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:18:2:18:38 | call to Post | tst.go:10:13:10:35 | call to FormValue : string | tst.go:18:12:18:18 | tainted | The $@ of this request depends on a $@. | tst.go:18:12:18:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:22:2:22:14 | call to Do | tst.go:10:13:10:35 | call to FormValue : string | tst.go:21:34:21:40 | tainted | The $@ of this request depends on a $@. | tst.go:21:34:21:40 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:25:2:25:14 | call to Do | tst.go:10:13:10:35 | call to FormValue : string | tst.go:24:66:24:72 | tainted | The $@ of this request depends on a $@. | tst.go:24:66:24:72 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:27:2:27:30 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:27:11:27:29 | ...+... | The $@ of this request depends on a $@. | tst.go:27:11:27:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:29:2:29:41 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:29:11:29:40 | ...+... | The $@ of this request depends on a $@. | tst.go:29:11:29:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| tst.go:37:2:37:21 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:37:11:37:20 | call to String | The $@ of this request depends on a $@. | tst.go:37:11:37:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue : string | user-provided value | -| websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer : string | user-provided value | -| websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer : string | user-provided value | -| websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer : string | user-provided value | -| websocket.go:110:3:110:39 | call to Dial | websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:110:15:110:28 | untrustedInput | WebSocket URL | websocket.go:107:21:107:31 | call to Referer : string | user-provided value | -| websocket.go:129:3:129:62 | call to DialContext | websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:129:38:129:51 | untrustedInput | WebSocket URL | websocket.go:126:21:126:31 | call to Referer : string | user-provided value | -| websocket.go:155:3:155:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:155:31:155:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer : string | user-provided value | -| websocket.go:162:3:162:45 | call to Dial | websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:162:31:162:44 | untrustedInput | WebSocket URL | websocket.go:160:21:160:31 | call to Referer : string | user-provided value | -| websocket.go:197:3:197:32 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:197:18:197:31 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer : string | user-provided value | -| websocket.go:204:3:204:25 | call to New | websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:204:11:204:24 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer : string | user-provided value | +| RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on a $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue | user-provided value | +| tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | The $@ of this request depends on a $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:18:2:18:38 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | The $@ of this request depends on a $@. | tst.go:18:12:18:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:22:2:22:14 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:21:34:21:40 | tainted | The $@ of this request depends on a $@. | tst.go:21:34:21:40 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:25:2:25:14 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:24:66:24:72 | tainted | The $@ of this request depends on a $@. | tst.go:24:66:24:72 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:27:2:27:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:27:11:27:29 | ...+... | The $@ of this request depends on a $@. | tst.go:27:11:27:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:29:2:29:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:29:11:29:40 | ...+... | The $@ of this request depends on a $@. | tst.go:29:11:29:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:37:2:37:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:37:11:37:20 | call to String | The $@ of this request depends on a $@. | tst.go:37:11:37:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer | user-provided value | +| websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer | user-provided value | +| websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer | user-provided value | +| websocket.go:110:3:110:39 | call to Dial | websocket.go:107:21:107:31 | call to Referer | websocket.go:110:15:110:28 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:110:15:110:28 | untrustedInput | WebSocket URL | websocket.go:107:21:107:31 | call to Referer | user-provided value | +| websocket.go:129:3:129:62 | call to DialContext | websocket.go:126:21:126:31 | call to Referer | websocket.go:129:38:129:51 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:129:38:129:51 | untrustedInput | WebSocket URL | websocket.go:126:21:126:31 | call to Referer | user-provided value | +| websocket.go:155:3:155:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer | websocket.go:155:31:155:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:155:31:155:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer | user-provided value | +| websocket.go:162:3:162:45 | call to Dial | websocket.go:160:21:160:31 | call to Referer | websocket.go:162:31:162:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:162:31:162:44 | untrustedInput | WebSocket URL | websocket.go:160:21:160:31 | call to Referer | user-provided value | +| websocket.go:197:3:197:32 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer | websocket.go:197:18:197:31 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:197:18:197:31 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer | user-provided value | +| websocket.go:204:3:204:25 | call to New | websocket.go:202:21:202:31 | call to Referer | websocket.go:204:11:204:24 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:204:11:204:24 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer | user-provided value | diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 189dbab6b94..496d7f2f9e3 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,130 +1,132 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,24,,103,,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,18,85 -android.content,24,31,154,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 -android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 -android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.core.app,6,,95,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,12,83 -androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 -com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, -java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 -java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,3,7, -java.nio,15,,14,,13,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,14, -java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -java.util,44,,461,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,12,,1835,,10,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,1828,7 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, -ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,106,,556,,91,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,542,14 -org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,2,,,,3,62,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:fragment-injection,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,35,,103,,,11,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,154,,,,,,,16,,,,,,,,,,,,,,,,,,8,,,,,,,,4,,27,,63,91 +android.database,59,,39,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,,39, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 +android.support.v4.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +android.util,6,16,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.core.app,6,,95,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,12,83 +androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +androidx.slice,2,5,88,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,85,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 +com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, +freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,40,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,40, +java.lang,13,,66,,,,,,,,,,,,8,,,,,,4,,,1,,,,,,,,,,,,,,,,54,12 +java.net,10,3,7,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,3,7, +java.nio,15,,16,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,16, +java.sql,11,,,,,,,,,,4,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +java.util,44,,461,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,,,,36,425 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin,12,,1835,,10,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,1828,7 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, +ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +okhttp3,2,,47,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,106,,560,,91,,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,546,14 +org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,2,,,,3,62,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +org.springframework.http,14,,70,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,2, +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 46da8bda328..c5258aa5d3e 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -7,21 +7,21 @@ Java framework & library support :widths: auto Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` - Android,``android.*``,52,479,116,,,3,67,,, - Android extensions,``androidx.*``,5,183,8,,,,,,, + Android,``android.*``,52,479,138,,,3,67,,, + Android extensions,``androidx.*``,5,183,19,,,,,,, `Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,, - `Apache Commons IO `_,``org.apache.commons.io``,,556,106,91,,,,,,15 - `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,,,,,,,, + `Apache Commons IO `_,``org.apache.commons.io``,,560,106,91,,,,,,15 + `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,6,,,,,,, `Apache Commons Text `_,``org.apache.commons.text``,,272,,,,,,,, `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Apache Log4j 2 `_,``org.apache.logging.log4j``,,8,359,,,,,,, `Google Guava `_,``com.google.common.*``,,728,39,,6,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,589,130,28,,,7,,,10 + Java Standard Library,``java.*``,3,591,130,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring `_,``org.springframework.*``,29,477,101,,,,19,14,,29 Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,269,,,,14,18,,3 - Totals,,217,8432,1524,129,6,10,107,33,1,86 + Totals,,217,8438,1563,129,6,10,107,33,1,86 diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme new file mode 100644 index 00000000000..44d61b266be --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/old.dbscheme @@ -0,0 +1,1246 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme new file mode 100644 index 00000000000..709f1d1fd04 --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/semmlecode.dbscheme @@ -0,0 +1,1240 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties new file mode 100644 index 00000000000..8d5b41b6e56 --- /dev/null +++ b/java/downgrades/44d61b266bebf261cb027872646262e645efa059/upgrade.properties @@ -0,0 +1,3 @@ +description: Remove compilation_info +compatibility: full +compilation_info.rel: delete diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 9525522869b..f31484bdec3 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -103,7 +103,7 @@ def compile_to_dir(srcs, classpath, java_classpath, output): '-classpath', os.path.pathsep.join([output, classpath, java_classpath])] + [s for s in srcs if s.endswith(".java")]) -def compile_to_jar(build_dir, srcs, classpath, java_classpath, output): +def compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, output): class_dir = build_dir + '/classes' if os.path.exists(class_dir): @@ -114,7 +114,8 @@ def compile_to_jar(build_dir, srcs, classpath, java_classpath, output): run_process(['jar', 'cf', output, '-C', class_dir, '.', - '-C', 'src/main/resources', 'META-INF']) + '-C', tmp_src_dir + '/main/resources', 'META-INF', + '-C', tmp_src_dir + '/main/resources', 'com/github/codeql/extractor.name']) shutil.rmtree(class_dir) @@ -146,18 +147,17 @@ def get_gradle_lib_folder(): return gradle_home + '/lib' -def find_jar(path, pattern): - result = glob.glob(path + '/' + pattern + '*.jar') - if len(result) == 0: - raise Exception('Cannot find jar file %s under path %s' % - (pattern, path)) - return result +def find_jar(path, base): + fn = path + '/' + base + '.jar' + if not os.path.isfile(fn): + raise Exception('Cannot find jar file at %s' % fn) + return fn -def patterns_to_classpath(path, patterns): +def bases_to_classpath(path, bases): result = [] - for pattern in patterns: - result += find_jar(path, pattern) + for base in bases: + result.append(find_jar(path, base)) return os.path.pathsep.join(result) @@ -173,8 +173,8 @@ def transform_to_embeddable(srcs): def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, build_dir, current_version): - classpath = patterns_to_classpath(dependency_folder, jars) - java_classpath = patterns_to_classpath(dependency_folder, java_jars) + classpath = bases_to_classpath(dependency_folder, jars) + java_classpath = bases_to_classpath(dependency_folder, java_jars) tmp_src_dir = build_dir + '/temp_src' @@ -185,6 +185,11 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, include_version_folder = tmp_src_dir + '/main/kotlin/utils/versions/to_include' os.makedirs(include_version_folder) + resource_dir = tmp_src_dir + '/main/resources/com/github/codeql' + os.makedirs(resource_dir) + with open(resource_dir + '/extractor.name', 'w') as f: + f.write(output) + parsed_current_version = kotlin_plugin_versions.version_string_to_tuple( current_version) @@ -211,7 +216,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, transform_to_embeddable(srcs) - compile_to_jar(build_dir, srcs, classpath, java_classpath, output) + compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, output) shutil.rmtree(tmp_src_dir) diff --git a/java/kotlin-extractor/gradle.properties b/java/kotlin-extractor/gradle.properties index 16f621c2d74..f9cd575cdd3 100644 --- a/java/kotlin-extractor/gradle.properties +++ b/java/kotlin-extractor/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlinVersion=1.7.0 +kotlinVersion=1.7.21 GROUP=com.github.codeql VERSION_NAME=0.0.1 diff --git a/java/kotlin-extractor/kotlin_plugin_versions.py b/java/kotlin-extractor/kotlin_plugin_versions.py index 04107005f8d..99691b89fd2 100755 --- a/java/kotlin-extractor/kotlin_plugin_versions.py +++ b/java/kotlin-extractor/kotlin_plugin_versions.py @@ -22,10 +22,10 @@ def version_string_to_tuple(version): return tuple([int(m.group(i)) for i in range(1, 4)] + [m.group(4)]) # Version number used by CI. It needs to be one of the versions in many_versions. -ci_version = '1.7.0' +ci_version = '1.7.20' # Version numbers in the list need to be in semantically increasing order -many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20-Beta' ] +many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20' ] many_versions_tuples = [version_string_to_tuple(v) for v in many_versions] diff --git a/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java b/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java index f238b93e41f..9859fd705b8 100644 --- a/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java +++ b/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java @@ -19,9 +19,10 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import com.github.codeql.Logger; -import static com.github.codeql.ClassNamesKt.getIrDeclBinaryName; +import static com.github.codeql.ClassNamesKt.getIrElementBinaryName; import static com.github.codeql.ClassNamesKt.getIrClassVirtualFile; +import org.jetbrains.kotlin.ir.IrElement; import org.jetbrains.kotlin.ir.declarations.IrClass; import com.intellij.openapi.vfs.VirtualFile; @@ -212,20 +213,19 @@ public class OdasaOutput { PathTransformer.std().fileAsDatabaseString(file) + ".trap.gz"); } - private File getTrapFileForDecl(IrDeclaration sym, String signature) { + private File getTrapFileForDecl(IrElement sym, String signature) { if (currentSpecFileEntry == null) return null; return trapFileForDecl(sym, signature); } - private File trapFileForDecl(IrDeclaration sym, String signature) { + private File trapFileForDecl(IrElement sym, String signature) { return FileUtil.fileRelativeTo(currentSpecFileEntry.getTrapFolder(), trapFilePathForDecl(sym, signature)); } - private String trapFilePathForDecl(IrDeclaration sym, String signature) { - String binaryName = getIrDeclBinaryName(sym); - String binaryNameWithSignature = binaryName + signature; + private String trapFilePathForDecl(IrElement sym, String signature) { + String binaryName = getIrElementBinaryName(sym); // TODO: Reinstate this? //if (getTrackClassOrigins()) // classId += "-" + StringDigestor.digest(sym.getSourceFileId()); @@ -241,7 +241,7 @@ public class OdasaOutput { * Deletion of existing trap files. */ - private void deleteTrapFileAndDependencies(IrDeclaration sym, String signature) { + private void deleteTrapFileAndDependencies(IrElement sym, String signature) { File trap = trapFileForDecl(sym, signature); if (trap.exists()) { trap.delete(); @@ -269,7 +269,7 @@ public class OdasaOutput { * Any unique suffix needed to distinguish `sym` from other declarations with the same name. * For functions for example, this means its parameter signature. */ - private TrapFileManager getMembersWriterForDecl(File trap, File trapFileBase, TrapClassVersion trapFileVersion, IrDeclaration sym, String signature) { + private TrapFileManager getMembersWriterForDecl(File trap, File trapFileBase, TrapClassVersion trapFileVersion, IrElement sym, String signature) { if (use_trap_locking) { TrapClassVersion currVersion = TrapClassVersion.fromSymbol(sym, log); String shortName = sym instanceof IrDeclarationWithName ? ((IrDeclarationWithName)sym).getName().asString() : "(name unknown)"; @@ -326,7 +326,7 @@ public class OdasaOutput { return trapWriter(trap, sym, signature); } - private TrapFileManager trapWriter(File trapFile, IrDeclaration sym, String signature) { + private TrapFileManager trapWriter(File trapFile, IrElement sym, String signature) { if (!trapFile.getName().endsWith(".trap.gz")) throw new CatastrophicError("OdasaOutput only supports writing to compressed trap files"); String relative = FileUtil.relativePath(trapFile, currentSpecFileEntry.getTrapFolder()); @@ -335,7 +335,7 @@ public class OdasaOutput { return concurrentWriter(trapFile, relative, log, sym, signature); } - private TrapFileManager concurrentWriter(File trapFile, String relative, Logger log, IrDeclaration sym, String signature) { + private TrapFileManager concurrentWriter(File trapFile, String relative, Logger log, IrElement sym, String signature) { if (trapFile.exists()) return null; return new TrapFileManager(trapFile, relative, true, log, sym, signature); @@ -345,11 +345,11 @@ public class OdasaOutput { private TrapDependencies trapDependenciesForClass; private File trapFile; - private IrDeclaration sym; + private IrElement sym; private String signature; private boolean hasError = false; - private TrapFileManager(File trapFile, String relative, boolean concurrentCreation, Logger log, IrDeclaration sym, String signature) { + private TrapFileManager(File trapFile, String relative, boolean concurrentCreation, Logger log, IrElement sym, String signature) { trapDependenciesForClass = new TrapDependencies(relative); this.trapFile = trapFile; this.sym = sym; @@ -360,7 +360,7 @@ public class OdasaOutput { return trapFile; } - public void addDependency(IrDeclaration dep, String signature) { + public void addDependency(IrElement dep, String signature) { trapDependenciesForClass.addDependency(trapFilePathForDecl(dep, signature)); } @@ -422,7 +422,7 @@ public class OdasaOutput { * previously set by a call to {@link OdasaOutput#setCurrentSourceFile(File)}. */ public TrapLocker getTrapLockerForCurrentSourceFile() { - return new TrapLocker((IrClass)null, null); + return new TrapLocker((IrClass)null, null, true); } /** @@ -460,19 +460,19 @@ public class OdasaOutput { * * @return a {@link TrapLocker} for the trap file corresponding to the given class symbol. */ - public TrapLocker getTrapLockerForDecl(IrDeclaration sym, String signature) { - return new TrapLocker(sym, signature); + public TrapLocker getTrapLockerForDecl(IrElement sym, String signature, boolean fromSource) { + return new TrapLocker(sym, signature, fromSource); } public class TrapLocker implements AutoCloseable { - private final IrDeclaration sym; + private final IrElement sym; private final File trapFile; // trapFileBase is used when doing lockless TRAP file writing. // It is trapFile without the #metadata.trap.gz suffix. private File trapFileBase = null; private TrapClassVersion trapFileVersion = null; private final String signature; - private TrapLocker(IrDeclaration decl, String signature) { + private TrapLocker(IrElement decl, String signature, boolean fromSource) { this.sym = decl; this.signature = signature; if (sym==null) { @@ -485,7 +485,10 @@ public class OdasaOutput { } else { // We encode the metadata into the filename, so that the // TRAP filenames for different metadatas don't overlap. - trapFileVersion = TrapClassVersion.fromSymbol(sym, log); + if (fromSource) + trapFileVersion = new TrapClassVersion(0, 0, 0, "kotlin"); + else + trapFileVersion = TrapClassVersion.fromSymbol(sym, log); String baseName = normalTrapFile.getName().replace(".trap.gz", ""); // If a class has lots of inner classes, then we get lots of files // in a single directory. This makes our directory listings later slow. @@ -717,11 +720,18 @@ public class OdasaOutput { return vf.getTimeStamp(); } - private static TrapClassVersion fromSymbol(IrDeclaration sym, Logger log) { - VirtualFile vf = sym instanceof IrClass ? getIrClassVirtualFile((IrClass)sym) : - sym.getParent() instanceof IrClass ? getIrClassVirtualFile((IrClass)sym.getParent()) : - null; - if(vf == null) + private static VirtualFile getVirtualFileIfClass(IrElement e) { + if (e instanceof IrClass) + return getIrClassVirtualFile((IrClass)e); + else + return null; + } + + private static TrapClassVersion fromSymbol(IrElement sym, Logger log) { + VirtualFile vf = getVirtualFileIfClass(sym); + if (vf == null && sym instanceof IrDeclaration) + vf = getVirtualFileIfClass(((IrDeclaration)sym).getParent()); + if (vf == null) return new TrapClassVersion(-1, 0, 0, null); final int[] versionStore = new int[1]; diff --git a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt index 12ea05a33c3..c45e0a454b7 100644 --- a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt @@ -1,16 +1,14 @@ package com.github.codeql -import com.github.codeql.utils.isExternalDeclaration import com.github.codeql.utils.isExternalFileClassMember import com.semmle.extractor.java.OdasaOutput import com.semmle.util.data.StringDigestor import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.isFileClass import org.jetbrains.kotlin.ir.util.packageFqName -import org.jetbrains.kotlin.ir.util.parentClassOrNull -import org.jetbrains.kotlin.name.FqName +import java.io.BufferedWriter import java.io.File import java.util.ArrayList import java.util.HashSet @@ -25,87 +23,103 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri val propertySignature = ";property" val fieldSignature = ";field" + val output = OdasaOutput(false, logger).also { + it.setCurrentSourceFile(File(sourceFilePath)) + } + fun extractLater(d: IrDeclarationWithName, signature: String): Boolean { if (d !is IrClass && !isExternalFileClassMember(d)) { logger.errorElement("External declaration is neither a class, nor a top-level declaration", d) return false } - val declBinaryName = declBinaryNames.getOrPut(d) { getIrDeclBinaryName(d) } + val declBinaryName = declBinaryNames.getOrPut(d) { getIrElementBinaryName(d) } val ret = externalDeclsDone.add(Pair(declBinaryName, signature)) if (ret) externalDeclWorkList.add(Pair(d, signature)) return ret } fun extractLater(c: IrClass) = extractLater(c, "") + fun writeStubTrapFile(e: IrElement, signature: String = "") { + extractElement(e, signature, true) { trapFileBW, _, _ -> + trapFileBW.write("// Trap file stubbed because this declaration was extracted from source in $sourceFilePath\n") + trapFileBW.write("// Part of invocation $invocationTrapFile\n") + } + } + + private fun extractElement(element: IrElement, possiblyLongSignature: String, fromSource: Boolean, extractorFn: (BufferedWriter, String, OdasaOutput.TrapFileManager) -> Unit) { + // In order to avoid excessively long signatures which can lead to trap file names longer than the filesystem + // limit, we truncate and add a hash to preserve uniqueness if necessary. + val signature = if (possiblyLongSignature.length > 100) { + possiblyLongSignature.substring(0, 92) + "#" + StringDigestor.digest(possiblyLongSignature).substring(0, 8) + } else { possiblyLongSignature } + output.getTrapLockerForDecl(element, signature, fromSource).useAC { locker -> + locker.trapFileManager.useAC { manager -> + val shortName = when(element) { + is IrDeclarationWithName -> element.name.asString() + is IrFile -> element.name + else -> "(unknown name)" + } + if (manager == null) { + logger.info("Skipping extracting external decl $shortName") + } else { + val trapFile = manager.file + val trapTmpFile = File.createTempFile("${trapFile.nameWithoutExtension}.", ".${trapFile.extension}.tmp", trapFile.parentFile) + try { + GZIPOutputStream(trapTmpFile.outputStream()).bufferedWriter().use { + extractorFn(it, signature, manager) + } + + if (!trapTmpFile.renameTo(trapFile)) { + logger.error("Failed to rename $trapTmpFile to $trapFile") + } + } catch (e: Exception) { + manager.setHasError() + logger.error("Failed to extract '$shortName'. Partial TRAP file location is $trapTmpFile", e) + } + } + } + } + } + fun extractExternalClasses() { - val output = OdasaOutput(false, logger) - output.setCurrentSourceFile(File(sourceFilePath)) do { val nextBatch = ArrayList(externalDeclWorkList) externalDeclWorkList.clear() nextBatch.forEach { workPair -> val (irDecl, possiblyLongSignature) = workPair - // In order to avoid excessively long signatures which can lead to trap file names longer than the filesystem - // limit, we truncate and add a hash to preserve uniqueness if necessary. - val signature = if (possiblyLongSignature.length > 100) { - possiblyLongSignature.substring(0, 92) + "#" + StringDigestor.digest(possiblyLongSignature).substring(0, 8) - } else { possiblyLongSignature } - output.getTrapLockerForDecl(irDecl, signature).useAC { locker -> - locker.trapFileManager.useAC { manager -> - val shortName = when(irDecl) { - is IrDeclarationWithName -> irDecl.name.asString() - else -> "(unknown name)" + extractElement(irDecl, possiblyLongSignature, false) { trapFileBW, signature, manager -> + val containingClass = getContainingClassOrSelf(irDecl) + if (containingClass == null) { + logger.errorElement("Unable to get containing class", irDecl) + } else { + val binaryPath = getIrClassBinaryPath(containingClass) + + // We want our comments to be the first thing in the file, + // so start off with a mere TrapWriter + val tw = TrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter) + tw.writeComment("Generated by the CodeQL Kotlin extractor for external dependencies") + tw.writeComment("Part of invocation $invocationTrapFile") + if (signature != possiblyLongSignature) { + tw.writeComment("Function signature abbreviated; full signature is: $possiblyLongSignature") } - if(manager == null) { - logger.info("Skipping extracting external decl $shortName") + // Now elevate to a SourceFileTrapWriter, and populate the + // file information if needed: + val ftw = tw.makeFileTrapWriter(binaryPath, true) + + val fileExtractor = KotlinFileExtractor(logger, ftw, null, binaryPath, manager, this, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState) + + if (irDecl is IrClass) { + // Populate a location and compilation-unit package for the file. This is similar to + // the beginning of `KotlinFileExtractor.extractFileContents` but without an `IrFile` + // to start from. + val pkg = irDecl.packageFqName?.asString() ?: "" + val pkgId = fileExtractor.extractPackage(pkg) + ftw.writeHasLocation(ftw.fileId, ftw.getWholeFileLocation()) + ftw.writeCupackage(ftw.fileId, pkgId) + + fileExtractor.extractClassSource(irDecl, extractDeclarations = !irDecl.isFileClass, extractStaticInitializer = false, extractPrivateMembers = false, extractFunctionBodies = false) } else { - val trapFile = manager.file - val trapTmpFile = File.createTempFile("${trapFile.nameWithoutExtension}.", ".${trapFile.extension}.tmp", trapFile.parentFile) - - val containingClass = getContainingClassOrSelf(irDecl) - if (containingClass == null) { - logger.errorElement("Unable to get containing class", irDecl) - return - } - val binaryPath = getIrClassBinaryPath(containingClass) - try { - GZIPOutputStream(trapTmpFile.outputStream()).bufferedWriter().use { trapFileBW -> - // We want our comments to be the first thing in the file, - // so start off with a mere TrapWriter - val tw = TrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter) - tw.writeComment("Generated by the CodeQL Kotlin extractor for external dependencies") - tw.writeComment("Part of invocation $invocationTrapFile") - if (signature != possiblyLongSignature) { - tw.writeComment("Function signature abbreviated; full signature is: $possiblyLongSignature") - } - // Now elevate to a SourceFileTrapWriter, and populate the - // file information if needed: - val ftw = tw.makeFileTrapWriter(binaryPath, true) - - val fileExtractor = KotlinFileExtractor(logger, ftw, null, binaryPath, manager, this, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState) - - if (irDecl is IrClass) { - // Populate a location and compilation-unit package for the file. This is similar to - // the beginning of `KotlinFileExtractor.extractFileContents` but without an `IrFile` - // to start from. - val pkg = irDecl.packageFqName?.asString() ?: "" - val pkgId = fileExtractor.extractPackage(pkg) - ftw.writeHasLocation(ftw.fileId, ftw.getWholeFileLocation()) - ftw.writeCupackage(ftw.fileId, pkgId) - - fileExtractor.extractClassSource(irDecl, extractDeclarations = !irDecl.isFileClass, extractStaticInitializer = false, extractPrivateMembers = false, extractFunctionBodies = false) - } else { - fileExtractor.extractDeclaration(irDecl, extractPrivateMembers = false, extractFunctionBodies = false) - } - } - - if (!trapTmpFile.renameTo(trapFile)) { - logger.error("Failed to rename $trapTmpFile to $trapFile") - } - } catch (e: Exception) { - manager.setHasError() - logger.error("Failed to extract '$shortName'. Partial TRAP file location is $trapTmpFile", e) - } + fileExtractor.extractDeclaration(irDecl, extractPrivateMembers = false, extractFunctionBodies = false, extractAnnotations = true) } } } diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt index c11d8569ae4..9bfcabd20fb 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt @@ -131,6 +131,9 @@ class KotlinExtractorExtension( // The interceptor has already defined #compilation = * val compilation: Label = StringLabel("compilation") tw.writeCompilation_started(compilation) + tw.writeCompilation_info(compilation, "Kotlin Compiler Version", KotlinCompilerVersion.getVersion() ?: "") + val extractor_name = this::class.java.getResource("extractor.name")?.readText() ?: "" + tw.writeCompilation_info(compilation, "Kotlin Extractor Name", extractor_name) if (compilationStartTime != null) { tw.writeCompilation_compiler_times(compilation, -1.0, (System.currentTimeMillis()-compilationStartTime)/1000.0) } @@ -204,6 +207,7 @@ class KotlinExtractorGlobalState { val syntheticToRealClassMap = HashMap() val syntheticToRealFunctionMap = HashMap() val syntheticToRealFieldMap = HashMap() + val syntheticRepeatableAnnotationContainers = HashMap() } /* diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 511b97fd4d0..faa83139bbb 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -2,9 +2,7 @@ package com.github.codeql import com.github.codeql.comments.CommentExtractor import com.github.codeql.utils.* -import com.github.codeql.utils.versions.allOverriddenIncludingSelf -import com.github.codeql.utils.versions.functionN -import com.github.codeql.utils.versions.isUnderscoreParameter +import com.github.codeql.utils.versions.* import com.semmle.extractor.java.OdasaOutput import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.lower.parents @@ -16,17 +14,46 @@ import org.jetbrains.kotlin.descriptors.java.JavaVisibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget +import org.jetbrains.kotlin.ir.builders.declarations.* 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.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.util.companionObject +import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.ir.util.hasAnnotation +import org.jetbrains.kotlin.ir.util.hasInterfaceParent +import org.jetbrains.kotlin.ir.util.isAnnotationClass +import org.jetbrains.kotlin.ir.util.isAnonymousObject +import org.jetbrains.kotlin.ir.util.isFakeOverride +import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction +import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.isLocal +import org.jetbrains.kotlin.ir.util.isNonCompanionObject +import org.jetbrains.kotlin.ir.util.isObject +import org.jetbrains.kotlin.ir.util.isSuspend +import org.jetbrains.kotlin.ir.util.isSuspendFunctionOrKFunction +import org.jetbrains.kotlin.ir.util.isVararg +import org.jetbrains.kotlin.ir.util.kotlinFqName +import org.jetbrains.kotlin.ir.util.packageFqName +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.parentClassOrNull +import org.jetbrains.kotlin.ir.util.primaryConstructor +import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.target +import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS +import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS import org.jetbrains.kotlin.load.java.sources.JavaSourceElement +import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaClass +import org.jetbrains.kotlin.load.java.structure.JavaConstructor import org.jetbrains.kotlin.load.java.structure.JavaMethod import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner @@ -34,6 +61,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.io.Closeable import java.util.* import kotlin.collections.ArrayList @@ -51,6 +79,8 @@ open class KotlinFileExtractor( globalExtensionState: KotlinExtractorGlobalState, ): KotlinUsesExtractor(logger, tw, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, globalExtensionState) { + val metaAnnotationSupport = MetaAnnotationSupport(logger, pluginContext, this) + private inline fun with(kind: String, element: IrElement, f: () -> T): T { val name = when (element) { is IrFile -> element.name @@ -90,7 +120,12 @@ open class KotlinFileExtractor( } } - file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) } + file.declarations.forEach { + extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true, extractAnnotations = true) + if (it is IrProperty || it is IrField || it is IrFunction) { + externalClassExtractor.writeStubTrapFile(it, getTrapFileSignature(it)) + } + } extractStaticInitializer(file, { extractFileClass(file) }) CommentExtractor(this, file, tw.fileId).extract() @@ -99,6 +134,8 @@ open class KotlinFileExtractor( } linesOfCode?.linesOfCodeInFile(id) + + externalClassExtractor.writeStubTrapFile(file) } } @@ -141,7 +178,7 @@ open class KotlinFileExtractor( private fun shouldExtractDecl(declaration: IrDeclaration, extractPrivateMembers: Boolean) = extractPrivateMembers || !isPrivate(declaration) - fun extractDeclaration(declaration: IrDeclaration, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { + fun extractDeclaration(declaration: IrDeclaration, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean, extractAnnotations: Boolean) { with("declaration", declaration) { if (!shouldExtractDecl(declaration, extractPrivateMembers)) return @@ -156,7 +193,7 @@ open class KotlinFileExtractor( is IrFunction -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractFunction(declaration, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, null, listOf()) + extractFunction(declaration, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = extractAnnotations, null, listOf()) } Unit } @@ -166,7 +203,7 @@ open class KotlinFileExtractor( is IrProperty -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, null, listOf()) + extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, extractAnnotations = extractAnnotations, null, listOf()) } Unit } @@ -180,7 +217,8 @@ open class KotlinFileExtractor( is IrField -> { val parentId = useDeclarationParent(getFieldParent(declaration), false)?.cast() if (parentId != null) { - extractField(declaration, parentId) + // For consistency with the Java extractor, enum entries get type accesses only if we're extracting from .kt source (i.e., when `extractFunctionBodies` is set) + extractField(declaration, parentId, extractAnnotationEnumTypeAccesses = extractFunctionBodies) } Unit } @@ -231,6 +269,8 @@ open class KotlinFileExtractor( addModifiers(id, "out") } + // extractAnnotations(tp, id) + // TODO: introduce annotations once they can be disambiguated from bounds, which are also child expressions. return id } } @@ -398,8 +438,8 @@ open class KotlinFileExtractor( } } when (d) { - is IrFunction -> extractFunction(d, parentId, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses) - is IrProperty -> extractProperty(d, parentId, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses) + is IrFunction -> extractFunction(d, parentId, extractBody = false, extractMethodAndParameterTypeAccesses = false, extractAnnotations = false, typeParamSubstitution, argsIncludingOuterClasses) + is IrProperty -> extractProperty(d, parentId, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, extractAnnotations = false, typeParamSubstitution, argsIncludingOuterClasses) else -> {} } } @@ -450,7 +490,137 @@ open class KotlinFileExtractor( extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) } } - val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic") + private val javaLangDeprecated by lazy { referenceExternalClass("java.lang.Deprecated") } + + private val javaLangDeprecatedConstructor by lazy { javaLangDeprecated?.constructors?.singleOrNull() } + + private fun replaceKotlinDeprecatedAnnotation(annotations: List): List { + val shouldReplace = + annotations.any { (it.type as? IrSimpleType)?.classFqName?.asString() == "kotlin.Deprecated" } && + annotations.none { it.type.classOrNull == javaLangDeprecated?.symbol } + val jldConstructor = javaLangDeprecatedConstructor + if (!shouldReplace || jldConstructor == null) + return annotations + return annotations.filter { (it.type as? IrSimpleType)?.classFqName?.asString() != "kotlin.Deprecated" } + + // Note we lose any arguments to @java.lang.Deprecated that were written in source. + IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, jldConstructor.returnType, jldConstructor.symbol, 0 + ) + } + + private fun extractAnnotations(c: IrAnnotationContainer, annotations: List, parent: Label, extractEnumTypeAccesses: Boolean) { + val origin = (c as? IrDeclaration)?.origin ?: run { logger.warn("Unexpected annotation container: $c"); return } + val replacedAnnotations = + if (origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) + replaceKotlinDeprecatedAnnotation(annotations) + else + annotations + val groupedAnnotations = metaAnnotationSupport.groupRepeatableAnnotations(replacedAnnotations) + for ((idx, constructorCall: IrConstructorCall) in groupedAnnotations.sortedBy { v -> v.type.classFqName?.asString() }.withIndex()) { + extractAnnotation(constructorCall, parent, idx, extractEnumTypeAccesses) + } + } + + private fun extractAnnotations(c: IrAnnotationContainer, parent: Label, extractEnumTypeAccesses: Boolean) { + extractAnnotations(c, c.annotations, parent, extractEnumTypeAccesses) + } + + private fun extractAnnotation( + constructorCall: IrConstructorCall, + parent: Label, + idx: Int, + extractEnumTypeAccesses: Boolean, + contextLabel: String? = null + ): Label { + // Erase the type here because the JVM lowering erases the annotation type, and so the Java extractor will see it in erased form. + val t = useType(erase(constructorCall.type)) + val annotationContextLabel = contextLabel ?: "{${t.javaResult.id}}" + val id = tw.getLabelFor("@\"annotation;{$parent};$annotationContextLabel\"") + tw.writeExprs_declannotation(id, t.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, t.kotlinResult.id) + + val locId = tw.getLocation(constructorCall) + tw.writeHasLocation(id, locId) + + for (i in 0 until constructorCall.valueArgumentsCount) { + val param = constructorCall.symbol.owner.valueParameters[i] + val prop = constructorCall.symbol.owner.parentAsClass.declarations + .filterIsInstance() + .first { it.name == param.name } + val v = constructorCall.getValueArgument(i) ?: param.defaultValue?.expression + val getter = prop.getter + if (getter == null) { + logger.warnElement("Expected annotation property to define a getter", prop) + } else { + val getterId = useFunction(getter) + val exprId = extractAnnotationValueExpression(v, id, i, "{${getterId}}", getter.returnType, extractEnumTypeAccesses) + if (exprId != null) { + tw.writeAnnotValue(id, getterId, exprId) + } + } + } + return id + } + + private fun extractAnnotationValueExpression( + v: IrExpression?, + parent: Label, + idx: Int, + contextLabel: String, + contextType: IrType?, + extractEnumTypeAccesses: Boolean): Label? { + + fun exprId() = tw.getLabelFor("@\"annotationExpr;{$parent};$idx\"") + + return when (v) { + is IrConst<*> -> { + extractConstant(v, parent, idx, null, null, overrideId = exprId()) + } + is IrGetEnumValue -> { + extractEnumValue(v, parent, idx, null, null, extractTypeAccess = extractEnumTypeAccesses, overrideId = exprId()) + } + is IrClassReference -> { + val classRefId = exprId() + val typeAccessId = tw.getLabelFor("@\"annotationExpr;{$classRefId};0\"") + extractClassReference(v, parent, idx, null, null, overrideId = classRefId, typeAccessOverrideId = typeAccessId, useJavaLangClassType = true) + } + is IrConstructorCall -> { + extractAnnotation(v, parent, idx, extractEnumTypeAccesses, contextLabel) + } + is IrVararg -> { + tw.getLabelFor("@\"annotationarray;{${parent}};$contextLabel\"").also { arrayId -> + // Use the context type (i.e., the type the annotation expects, not the actual type of the array) + // because the Java extractor fills in array types using the same technique. These should only + // differ for generic annotations. + if (contextType == null) { + logger.warnElement("Expected an annotation array to have an enclosing context", v) + } else { + val type = useType(kClassToJavaClass(contextType)) + tw.writeExprs_arrayinit(arrayId, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(arrayId, type.kotlinResult.id) + tw.writeHasLocation(arrayId, tw.getLocation(v)) + + v.elements.forEachIndexed { index, irVarargElement -> run { + val argExpr = when (irVarargElement) { + is IrExpression -> irVarargElement + is IrSpreadElement -> irVarargElement.expression + else -> { + logger.errorElement("Unrecognised IrVarargElement: " + irVarargElement.javaClass, irVarargElement) + null + } + } + extractAnnotationValueExpression(argExpr, arrayId, index, "child;$index", null, extractEnumTypeAccesses) + } } + } + } + } + // is IrErrorExpression + // null + // Note: emitting an ErrorExpr here would induce an inconsistency if this annotation is later seen from source or by the Java extractor, + // in both of which cases the real value will get extracted. + else -> null + } + } fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label { with("class source", c) { @@ -463,6 +633,10 @@ open class KotlinFileExtractor( if (c.isInterfaceLike) { val interfaceId = id.cast() tw.writeInterfaces(interfaceId, cls, pkgId, interfaceId) + + if (c.kind == ClassKind.ANNOTATION_CLASS) { + tw.writeIsAnnotType(interfaceId) + } } else { val classId = id.cast() tw.writeClasses(classId, cls, pkgId, classId) @@ -488,10 +662,25 @@ open class KotlinFileExtractor( c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) } if (extractDeclarations) { - c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) } - if (extractStaticInitializer) - extractStaticInitializer(c, { id }) - extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies) + if (c.kind == ClassKind.ANNOTATION_CLASS) { + c.declarations + .filterIsInstance() + .forEach { + val getter = it.getter + if (getter == null) { + logger.warnElement("Expected an annotation property to have a getter", it) + } else { + extractFunction(getter, id, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = true, null, listOf())?.also { functionLabel -> + tw.writeIsAnnotElem(functionLabel.cast()) + } + } + } + } else { + c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies, extractAnnotations = true) } + if (extractStaticInitializer) + extractStaticInitializer(c, { id }) + extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies) + } } if (c.isNonCompanionObject) { // For `object MyObject { ... }`, the .class has an @@ -507,6 +696,9 @@ open class KotlinFileExtractor( addModifiers(instance.id, "public", "static", "final") tw.writeClass_object(id.cast(), instance.id) } + if (c.isObject) { + addModifiers(id, "static") + } if (extractFunctionBodies && needsObinitFunction(c)) { extractObinitFunction(c, id) } @@ -516,11 +708,24 @@ open class KotlinFileExtractor( linesOfCode?.linesOfCodeInDeclaration(c, id) + val additionalAnnotations = + if (c.kind == ClassKind.ANNOTATION_CLASS && c.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) + metaAnnotationSupport.generateJavaMetaAnnotations(c, extractFunctionBodies) + else + listOf() + + extractAnnotations(c, c.annotations + additionalAnnotations, id, extractFunctionBodies) + + if (extractFunctionBodies && !c.isAnonymousObject && !c.isLocal) + externalClassExtractor.writeStubTrapFile(c) + return id } } } + val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic") + private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { // Add synthetic forwarders for any JvmStatic methods or properties: @@ -534,7 +739,7 @@ open class KotlinFileExtractor( val proxyFunctionId = tw.getLabelFor(getFunctionLabel(f, classId, listOf())) // We extract the function prototype with its ID overridden to belong to `c` not the companion object, // but suppress outputting the body, which we will replace with a delegating call below. - forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), extractOrigin = false, OverriddenFunctionAttributes(id = proxyFunctionId)) + forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = false, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), extractOrigin = false, OverriddenFunctionAttributes(id = proxyFunctionId)) addModifiers(proxyFunctionId, "static") tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind) if (extractFunctionBodies) { @@ -701,6 +906,13 @@ open class KotlinFileExtractor( extractTypeAccessRecursive(substitutedType, location, id, -1) } val syntheticParameterNames = isUnderscoreParameter(vp) || ((vp.parent as? IrFunction)?.let { hasSynthesizedParameterNames(it) } ?: true) + val javaParameter = when(val callable = (vp.parent as? IrFunction)?.let { getJavaCallable(it) }) { + is JavaConstructor -> callable.valueParameters.getOrNull(idx) + is JavaMethod -> callable.valueParameters.getOrNull(idx) + else -> null + } + val extraAnnotations = listOfNotNull(getNullabilityAnnotation(vp.type, vp.origin, vp.annotations, javaParameter?.annotations)) + extractAnnotations(vp, vp.annotations + extraAnnotations, id, extractTypeAccess) return extractValueParameter(id, substitutedType, vp.name.asString(), location, parent, idx, useValueParameter(vp, parentSourceDeclaration), syntheticParameterNames, vp.isVararg, vp.isNoinline, vp.isCrossinline) } } @@ -878,7 +1090,7 @@ open class KotlinFileExtractor( f.realOverrideTarget.let { it != f && (it as? IrSimpleFunction)?.modality != Modality.ABSTRACT && isKotlinDefinedInterface(it.parentClassOrNull) } private fun makeInterfaceForwarder(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = - forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = OverriddenFunctionAttributes(visibility = DescriptorVisibilities.PUBLIC)).also { functionId -> + forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, extractAnnotations = false, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = OverriddenFunctionAttributes(visibility = DescriptorVisibilities.PUBLIC, modality = Modality.OPEN)).also { functionId -> tw.writeCompiler_generated(functionId, CompilerGeneratedKinds.INTERFACE_FORWARDER.kind) if (extractBody) { val realFunctionLocId = tw.getLocation(f) @@ -919,7 +1131,7 @@ open class KotlinFileExtractor( } } - private fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = + private fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, extractAnnotations: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = if (isFake(f)) { if (needsInterfaceForwarder(f)) makeInterfaceForwarder(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses) @@ -928,7 +1140,7 @@ open class KotlinFileExtractor( } else { // Work around an apparent bug causing redeclarations of `fun toString(): String` specifically in interfaces loaded from Java classes show up like fake overrides. val overriddenVisibility = if (f.isFakeOverride && isJavaBinaryObjectMethodRedeclaration(f)) OverriddenFunctionAttributes(visibility = DescriptorVisibilities.PUBLIC) else null - forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = overriddenVisibility).also { + forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, extractAnnotations, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = overriddenVisibility).also { // The defaults-forwarder function is a static utility, not a member, so we only need to extract this for the unspecialised instance of this class. if (classTypeArgsIncludingOuterClasses.isNullOrEmpty()) extractDefaultsFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses) @@ -944,7 +1156,7 @@ open class KotlinFileExtractor( val locId = getLocation(f, null) val extReceiver = f.extensionReceiverParameter val dispatchReceiver = if (f.shouldExtractAsStatic) null else f.dispatchReceiverParameter - val parameterTypes = listOfNotNull(extReceiver?.let { erase(it.type) }) + getDefaultsMethodArgTypes(f) + val parameterTypes = getDefaultsMethodArgTypes(f) val allParamTypeResults = parameterTypes.mapIndexed { i, paramType -> val paramId = tw.getLabelFor(getValueParameterLabel(id, i)) extractValueParameter(paramId, paramType, "p$i", locId, id, i, paramId, isVararg = false, syntheticParameterNames = true, isCrossinline = false, isNoinline = false).also { @@ -962,6 +1174,11 @@ open class KotlinFileExtractor( val methodId = id.cast() extractMethod(methodId, locId, shortName, erase(f.returnType), paramsSignature, parentId, methodId, origin = null, extractTypeAccess = extractMethodAndParameterTypeAccesses) addModifiers(id, "static") + if (extReceiver != null) { + val idx = if (dispatchReceiver != null) 1 else 0 + val extendedType = allParamTypeResults[idx] + tw.writeKtExtensionFunctions(methodId, extendedType.javaResult.id, extendedType.kotlinResult.id) + } } tw.writeHasLocation(id, locId) if (f.visibility != DescriptorVisibilities.PRIVATE && f.visibility != DescriptorVisibilities.PRIVATE_TO_THIS) { @@ -1027,8 +1244,8 @@ open class KotlinFileExtractor( val realFnIdxOffset = if (f.extensionReceiverParameter != null) 1 else 0 val paramMappings = f.valueParameters.mapIndexed { idx, param -> Triple(param.type, idx + paramIdxOffset, idx + realFnIdxOffset) } + listOfNotNull( - dispatchReceiver?.let { Triple(it.type, realFnIdxOffset, -1) }, - extReceiver?.let { Triple(it.type, 0, 0) } + dispatchReceiver?.let { Triple(it.type, 0, -1) }, + extReceiver?.let { Triple(it.type, if (dispatchReceiver != null) 1 else 0, 0) } ) paramMappings.forEach { (type, fromIdx, toIdx) -> extractVariableAccess(tw.getLabelFor(getValueParameterLabel(id, fromIdx)), type, locId, thisCallId, toIdx, id, returnId) @@ -1049,8 +1266,6 @@ open class KotlinFileExtractor( private val jvmOverloadsFqName = FqName("kotlin.jvm.JvmOverloads") private fun extractGeneratedOverloads(f: IrFunction, parentId: Label, maybeSourceParentId: Label?, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { - if (!f.hasAnnotation(jvmOverloadsFqName)) - return fun extractGeneratedOverload(paramList: List) { val overloadParameters = paramList.filterNotNull() @@ -1066,7 +1281,7 @@ open class KotlinFileExtractor( parentId val sourceDeclId = tw.getLabelFor(getFunctionLabel(f, sourceParentId, listOf(), overloadParameters)) val overriddenAttributes = OverriddenFunctionAttributes(id = overloadId, sourceDeclarationId = sourceDeclId, valueParameters = overloadParameters) - forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = overriddenAttributes) + forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, extractAnnotations = false, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = overriddenAttributes) tw.writeCompiler_generated(overloadId, CompilerGeneratedKinds.JVMOVERLOADS_METHOD.kind) val realFunctionLocId = tw.getLocation(f) if (extractBody) { @@ -1096,6 +1311,22 @@ open class KotlinFileExtractor( } } + if (!f.hasAnnotation(jvmOverloadsFqName)) { + if (f is IrConstructor && + f.valueParameters.isNotEmpty() && + f.valueParameters.all { it.defaultValue != null } && + f.parentClassOrNull?.let { + // Don't create a default constructor for an annotation class, or a class that explicitly declares a no-arg constructor. + !it.isAnnotationClass && + it.declarations.none { d -> d is IrConstructor && d.valueParameters.isEmpty() } + } == true) { + // Per https://kotlinlang.org/docs/classes.html#creating-instances-of-classes, a single default overload gets created specifically + // when we have all default parameters, regardless of `@JvmOverloads`. + extractGeneratedOverload(f.valueParameters.map { _ -> null }) + } + return + } + val paramList: MutableList = f.valueParameters.toMutableList() for (n in (f.valueParameters.size - 1) downTo 0) { if (f.valueParameters[n].defaultValue != null) { @@ -1136,7 +1367,38 @@ open class KotlinFileExtractor( logger.warn("Needed a signature for a type that doesn't have one") } - private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, extractOrigin: Boolean = true, overriddenAttributes: OverriddenFunctionAttributes? = null): Label { + private fun getNullabilityAnnotationName(t: IrType, declOrigin: IrDeclarationOrigin, existingAnnotations: List, javaAnnotations: Collection?): FqName? { + if (t !is IrSimpleType) + return null + + fun hasExistingAnnotation(name: FqName) = + existingAnnotations.any { existing -> existing.type.classFqName == name } + + return if (declOrigin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) { + // Java declaration: restore a NotNull or Nullable annotation if the original Java member had one but the Kotlin compiler removed it. + javaAnnotations?.mapNotNull { it.classId?.asSingleFqName() } + ?.singleOrNull { NOT_NULL_ANNOTATIONS.contains(it) || NULLABLE_ANNOTATIONS.contains(it) } + ?.takeUnless { hasExistingAnnotation(it) } + } else { + // Kotlin declaration: add a NotNull annotation to a non-nullable non-primitive type, unless one is already present. + // Usually Kotlin declarations can't have a manual `@NotNull`, but this happens at least when delegating members are + // synthesised and inherit the annotation from the delegate (which given it has @NotNull, is likely written in Java) + JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.takeUnless { t.isNullable() || primitiveTypeMapping.getPrimitiveInfo(t) != null || hasExistingAnnotation(it) } + } + } + + private fun getNullabilityAnnotation(t: IrType, declOrigin: IrDeclarationOrigin, existingAnnotations: List, javaAnnotations: Collection?) = + getNullabilityAnnotationName(t, declOrigin, existingAnnotations, javaAnnotations)?.let { + pluginContext.referenceClass(it)?.let { annotationClass -> + annotationClass.owner.declarations.firstIsInstanceOrNull()?.let { annotationConstructor -> + IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, annotationConstructor.returnType, annotationConstructor.symbol, 0 + ) + } + } + } + + private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, extractAnnotations: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, extractOrigin: Boolean = true, overriddenAttributes: OverriddenFunctionAttributes? = null): Label { with("function", f) { DeclarationStackAdjuster(f, overriddenAttributes).use { @@ -1157,6 +1419,7 @@ open class KotlinFileExtractor( id val extReceiver = f.extensionReceiverParameter + // The following parameter order is correct, because member $default methods (where the order would be [dispatchParam], [extensionParam], normalParams) are not extracted here val fParameters = listOfNotNull(extReceiver) + (overriddenAttributes?.valueParameters ?: f.valueParameters) val paramTypes = fParameters.mapIndexed { i, vp -> extractValueParameter(vp, id, i, typeSubstitution, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, overriddenAttributes?.sourceLoc) @@ -1216,9 +1479,25 @@ open class KotlinFileExtractor( if (f.isSuspend) { addModifiers(id, "suspend") } + if (f.symbol !is IrConstructorSymbol) { + when(overriddenAttributes?.modality ?: (f as? IrSimpleFunction)?.modality) { + Modality.ABSTRACT -> addModifiers(id, "abstract") + Modality.FINAL -> addModifiers(id, "final") + else -> Unit + } + } linesOfCode?.linesOfCodeInDeclaration(f, id) + if (extractAnnotations) { + val extraAnnotations = + if (f.symbol is IrConstructorSymbol) + listOf() + else + listOfNotNull(getNullabilityAnnotation(f.returnType, f.origin, f.annotations, getJavaCallable(f)?.annotations)) + extractAnnotations(f, f.annotations + extraAnnotations, id, extractMethodAndParameterTypeAccesses) + } + return id } } @@ -1230,18 +1509,20 @@ open class KotlinFileExtractor( && f.symbol !is IrConstructorSymbol // not a constructor } - private fun extractField(f: IrField, parentId: Label): Label { + private fun extractField(f: IrField, parentId: Label, extractAnnotationEnumTypeAccesses: Boolean): Label { with("field", f) { DeclarationStackAdjuster(f).use { val fNameSuffix = getExtensionReceiverType(f)?.let { it.classFqName?.asString()?.replace(".", "$$") } ?: "" val extractType = if (isAnnotationClassField(f)) kClassToJavaClass(f.type) else f.type - return extractField(useField(f), "${f.name.asString()}$fNameSuffix", extractType, parentId, tw.getLocation(f), f.visibility, f, isExternalDeclaration(f), f.isFinal) + val id = useField(f) + extractAnnotations(f, id, extractAnnotationEnumTypeAccesses) + return extractField(id, "${f.name.asString()}$fNameSuffix", extractType, parentId, tw.getLocation(f), f.visibility, f, isExternalDeclaration(f), f.isFinal, isDirectlyExposedCompanionObjectField(f)) } } } - private fun extractField(id: Label, name: String, type: IrType, parentId: Label, locId: Label, visibility: DescriptorVisibility, errorElement: IrElement, isExternalDeclaration: Boolean, isFinal: Boolean): Label { + private fun extractField(id: Label, name: String, type: IrType, parentId: Label, locId: Label, visibility: DescriptorVisibility, errorElement: IrElement, isExternalDeclaration: Boolean, isFinal: Boolean, isStatic: Boolean): Label { val t = useType(type) tw.writeFields(id, name, t.javaResult.id, parentId, id) tw.writeFieldsKotlinType(id, t.kotlinResult.id) @@ -1251,6 +1532,9 @@ open class KotlinFileExtractor( if (isFinal) { addModifiers(id, "final") } + if (isStatic) { + addModifiers(id, "static") + } if (!isExternalDeclaration) { val fieldDeclarationId = tw.getFreshIdLabel() @@ -1264,7 +1548,7 @@ open class KotlinFileExtractor( return id } - private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { + private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, extractAnnotations: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { with("property", p) { fun needsInterfaceForwarderQ(f: IrFunction?) = f?.let { needsInterfaceForwarder(f) } ?: false @@ -1286,7 +1570,7 @@ open class KotlinFileExtractor( logger.warnElement("IrProperty without a getter", p) } } else if (shouldExtractDecl(getter, extractPrivateMembers)) { - val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() + val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = extractAnnotations, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (getterId != null) { tw.writeKtPropertyGetters(id, getterId) if (getter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { @@ -1303,7 +1587,7 @@ open class KotlinFileExtractor( if (!p.isVar) { logger.warnElement("!isVar property with a setter", p) } - val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() + val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = extractAnnotations, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (setterId != null) { tw.writeKtPropertySetters(id, setterId) if (setter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { @@ -1315,7 +1599,7 @@ open class KotlinFileExtractor( if (bf != null && extractBackingField) { val fieldParentId = useDeclarationParent(getFieldParent(bf), false) if (fieldParentId != null) { - val fieldId = extractField(bf, fieldParentId.cast()) + val fieldId = extractField(bf, fieldParentId.cast(), extractFunctionBodies) tw.writeKtPropertyBackingFields(id, fieldId) if (p.isDelegated) { tw.writeKtPropertyDelegates(id, fieldId) @@ -1325,6 +1609,8 @@ open class KotlinFileExtractor( extractVisibility(p, id, p.visibility) + // TODO: extract annotations + if (p.isLateinit) { addModifiers(id, "lateinit") } @@ -1366,8 +1652,10 @@ open class KotlinFileExtractor( } ee.correspondingClass?.let { - extractDeclaration(it, extractPrivateMembers, extractFunctionBodies) + extractDeclaration(it, extractPrivateMembers, extractFunctionBodies, extractAnnotations = true) } + + extractAnnotations(ee, id, extractFunctionBodies) } } } @@ -1384,6 +1672,8 @@ open class KotlinFileExtractor( val type = useType(ta.expandedType) tw.writeKt_type_alias(id, ta.name.asString(), type.kotlinResult.id) tw.writeHasLocation(id, locId) + + // TODO: extract annotations } } @@ -1507,14 +1797,15 @@ open class KotlinFileExtractor( } is IrFunction -> { if (s.isLocalFunction()) { - val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType)) + val compilerGeneratedKindOverride = if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { + CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS + } else { + null + } + val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType), compilerGeneratedKindOverride = compilerGeneratedKindOverride) extractLocalTypeDeclStmt(classId, s, callable, parent, idx) val ids = getLocallyVisibleFunctionLabels(s) tw.writeKtLocalFunction(ids.function) - - if (s.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { - tw.writeCompiler_generated(classId, CompilerGeneratedKinds.DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS.kind) - } } else { logger.errorElement("Expected to find local function", s) } @@ -1736,11 +2027,7 @@ open class KotlinFileExtractor( tw.writeCallableBinding(id, methodLabel) } - private val defaultConstructorMarkerClass by lazy { - val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.DefaultConstructorMarker"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + private val defaultConstructorMarkerClass by lazy { referenceExternalClass("kotlin.jvm.internal.DefaultConstructorMarker") } private val defaultConstructorMarkerType by lazy { defaultConstructorMarkerClass?.typeWith() @@ -1755,11 +2042,12 @@ open class KotlinFileExtractor( ) ?: pluginContext.irBuiltIns.anyType private fun getDefaultsMethodArgTypes(f: IrFunction) = - // The $default method has type ([extensionReceiver], [dispatchReceiver], paramTypes..., int, Object) + // The $default method has type ([dispatchReceiver], [extensionReceiver], paramTypes..., int, Object) // All parameter types are erased. The trailing int is a mask indicating which parameter values are real // and which should be replaced by defaults. The final Object parameter is apparently always null. ( listOfNotNull(if (f.shouldExtractAsStatic) null else f.dispatchReceiverParameter?.type) + + listOfNotNull(f.extensionReceiverParameter?.type) + f.valueParameters.map { it.type } + listOf(pluginContext.irBuiltIns.intType, getDefaultsMethodLastArgType(f)) ).map { erase(it) } @@ -1778,17 +2066,16 @@ open class KotlinFileExtractor( private fun getDefaultsMethodLabel(f: IrFunction): Label { val defaultsMethodName = if (f is IrConstructor) "" else getDefaultsMethodName(f) - val normalArgTypes = getDefaultsMethodArgTypes(f) - val extensionParamType = f.extensionReceiverParameter?.let { erase(it.type) } + val argTypes = getDefaultsMethodArgTypes(f) val defaultMethodLabelStr = getFunctionLabel( f.parent, maybeParentId = null, defaultsMethodName, - normalArgTypes, + argTypes, erase(f.returnType), - extensionParamType, - listOf(), + extensionParamType = null, // if there's any, that's included already in argTypes + functionTypeParameters = listOf(), classTypeArgsIncludingOuterClasses = null, overridesCollectionsMethod = false, javaSignature = null, @@ -1848,13 +2135,14 @@ open class KotlinFileExtractor( extensionReceiver: IrExpression? ) { var nextIdx = 0 - if (extensionReceiver != null) { - extractExpressionExpr(extensionReceiver, enclosingCallable, id, nextIdx++, enclosingStmt) - } if (dispatchReceiver != null && !callTarget.shouldExtractAsStatic) { extractExpressionExpr(dispatchReceiver, enclosingCallable, id, nextIdx++, enclosingStmt) } + if (extensionReceiver != null) { + extractExpressionExpr(extensionReceiver, enclosingCallable, id, nextIdx++, enclosingStmt) + } + val valueArgsWithDummies = valueArguments.zip(callTarget.valueParameters).map { (expr, param) -> expr ?: IrConstImpl.defaultValueForType(0, 0, param.type) } @@ -2057,7 +2345,7 @@ open class KotlinFileExtractor( extractValueArguments(argParent, idxOffset) } - private fun extractStaticTypeAccessQualifierUnchecked(parent: IrDeclarationParent, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) { + private fun extractStaticTypeAccessQualifierUnchecked(parent: IrDeclarationParent, parentExpr: Label, locId: Label, enclosingCallable: Label?, enclosingStmt: Label?) { if (parent is IrClass) { extractTypeAccessRecursive(parent.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt) } else if (parent is IrFile) { @@ -2067,7 +2355,7 @@ open class KotlinFileExtractor( } } - private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) { + private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label?, enclosingStmt: Label?) { if (target.shouldExtractAsStatic) { extractStaticTypeAccessQualifierUnchecked(target.parent, parentExpr, locId, enclosingCallable, enclosingStmt) } @@ -2102,11 +2390,7 @@ open class KotlinFileExtractor( private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.findSubType { it.name.asString() == name } - val jvmIntrinsicsClass by lazy { - val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val jvmIntrinsicsClass by lazy { referenceExternalClass("kotlin.jvm.internal.Intrinsics") } private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? { val result = jvmIntrinsicsClass?.let { findFunction(it, name) } @@ -2152,11 +2436,7 @@ open class KotlinFileExtractor( return prop } - val javaLangString by lazy { - val result = pluginContext.referenceClass(FqName("java.lang.String"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val javaLangString by lazy { referenceExternalClass("java.lang.String") } val stringValueOfObjectMethod by lazy { val result = javaLangString?.declarations?.findSubType { @@ -2180,11 +2460,7 @@ open class KotlinFileExtractor( result } - val kotlinNoWhenBranchMatchedExn by lazy { - val result = pluginContext.referenceClass(FqName("kotlin.NoWhenBranchMatchedException"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val kotlinNoWhenBranchMatchedExn by lazy {referenceExternalClass("kotlin.NoWhenBranchMatchedException") } val kotlinNoWhenBranchMatchedConstructor by lazy { val result = kotlinNoWhenBranchMatchedExn?.declarations?.findSubType { @@ -2196,11 +2472,7 @@ open class KotlinFileExtractor( result } - val javaUtilArrays by lazy { - val result = pluginContext.referenceClass(FqName("java.util.Arrays"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val javaUtilArrays by lazy { referenceExternalClass("java.util.Arrays") } private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, vararg fNames: String, isNullable: Boolean? = false) = fNames.any { isFunction(target, pkgName, classNameLogged, classNamePredicate, it, isNullable) } @@ -3348,10 +3620,10 @@ open class KotlinFileExtractor( extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt)) } - private fun extractExprContext(id: Label, locId: Label, callable: Label, enclosingStmt: Label) { + private fun extractExprContext(id: Label, locId: Label, callable: Label?, enclosingStmt: Label?) { tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, enclosingStmt) + callable?.let { tw.writeCallableEnclosingExpr(id, it) } + enclosingStmt?.let { tw.writeStatementEnclosingExpr(id, it) } } private fun extractEqualsExpression(locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) = @@ -3370,8 +3642,8 @@ open class KotlinFileExtractor( extractExprContext(it, locId, callable, enclosingStmt) } - private fun extractConstantInteger(v: Number, locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) = - tw.getFreshIdLabel().also { + private fun extractConstantInteger(v: Number, locId: Label, parent: Label, idx: Int, callable: Label?, enclosingStmt: Label?, overrideId: Label? = null) = + exprIdOrFresh(overrideId).also { val type = useType(pluginContext.irBuiltIns.intType) tw.writeExprs_integerliteral(it, type.javaResult.id, parent, idx) tw.writeExprsKotlinType(it, type.kotlinResult.id) @@ -3379,8 +3651,8 @@ open class KotlinFileExtractor( extractExprContext(it, locId, callable, enclosingStmt) } - private fun extractNull(t: IrType, locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) = - tw.getFreshIdLabel().also { + private fun extractNull(t: IrType, locId: Label, parent: Label, idx: Int, callable: Label?, enclosingStmt: Label?, overrideId: Label? = null) = + exprIdOrFresh(overrideId).also { val type = useType(t) tw.writeExprs_nullliteral(it, type.javaResult.id, parent, idx) tw.writeExprsKotlinType(it, type.kotlinResult.id) @@ -3545,72 +3817,7 @@ open class KotlinFileExtractor( } is IrConst<*> -> { val exprParent = parent.expr(e, callable) - val v = e.value - when { - v is Number && (v is Int || v is Short || v is Byte) -> { - extractConstantInteger(v, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) - } - v is Long -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_longliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v is Float -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_floatingpointliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v is Double -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_doubleliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v is Boolean -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_booleanliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v is Char -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_characterliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v is String -> { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_stringliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - tw.writeNamestrings(v.toString(), v.toString(), id) - } - v == null -> { - extractNull(e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) - } - else -> { - logger.errorElement("Unrecognised IrConst: " + v.javaClass, e) - } - } + extractConstant(e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) } is IrGetValue -> { val exprParent = parent.expr(e, callable) @@ -3639,19 +3846,7 @@ open class KotlinFileExtractor( } is IrGetEnumValue -> { val exprParent = parent.expr(e, callable) - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - - val owner = getBoundSymbolOwner(e.symbol, e) ?: return - - val vId = useEnumEntry(owner) - tw.writeVariableBinding(id, vId) - - extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt) + extractEnumValue(e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) } is IrSetValue, is IrSetField -> { @@ -3895,14 +4090,7 @@ open class KotlinFileExtractor( } is IrClassReference -> { val exprParent = parent.expr(e, callable) - val id = tw.getFreshIdLabel() - val locId = tw.getLocation(e) - val type = useType(e.type) - tw.writeExprs_typeliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - extractExprContext(id, locId, callable, exprParent.enclosingStmt) - - extractTypeAccessRecursive(e.classType, locId, id, 0, callable, exprParent.enclosingStmt) + extractClassReference(e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) } is IrPropertyReference -> { extractPropertyReference("property reference", e, e.getter, e.setter, e.field, parent, callable) @@ -3991,8 +4179,7 @@ open class KotlinFileExtractor( // Use of 'this' in a function where the dispatch receiver is passed like an ordinary parameter, // such as a `$default` static function that substitutes in default arguments as needed. val paramDeclarerId = overriddenAttributes.id ?: useDeclarationParent(thisParamParent, false) - val extensionParamOffset = if (thisParamParent.extensionReceiverParameter != null) 1 else 0 - val replacementParamId = tw.getLabelFor(getValueParameterLabel(paramDeclarerId, replaceWithParamIdx + extensionParamOffset)) + val replacementParamId = tw.getLabelFor(getValueParameterLabel(paramDeclarerId, replaceWithParamIdx)) extractVariableAccess(replacementParamId, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) return } @@ -4101,6 +4288,158 @@ open class KotlinFileExtractor( extractExpressionExpr(loop.condition, callable, id, 0, id) } + private fun exprIdOrFresh(id: Label?) = id?.cast() ?: tw.getFreshIdLabel() + + private fun extractClassReference( + e: IrClassReference, + parent: Label, + idx: Int, + enclosingCallable: Label?, + enclosingStmt: Label?, + overrideId: Label? = null, + typeAccessOverrideId: Label? = null, + useJavaLangClassType: Boolean = false + ) = + exprIdOrFresh(overrideId).also { id -> + val locId = tw.getLocation(e) + val jlcType = if (useJavaLangClassType) this.javaLangClass?.let { it.typeWith() } else null + val type = useType(jlcType ?: e.type) + tw.writeExprs_typeliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + + extractTypeAccessRecursive(e.classType, locId, id, 0, enclosingCallable, enclosingStmt, overrideId = typeAccessOverrideId) + } + + private fun extractEnumValue( + e: IrGetEnumValue, + parent: Label, + idx: Int, + enclosingCallable: Label?, + enclosingStmt: Label?, + extractTypeAccess: Boolean = true, + overrideId: Label? = null + ) = + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_varaccess(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + + getBoundSymbolOwner(e.symbol, e)?.let { owner -> + + val vId = useEnumEntry(owner) + tw.writeVariableBinding(id, vId) + + if (extractTypeAccess) + extractStaticTypeAccessQualifier(owner, id, locId, enclosingCallable, enclosingStmt) + + } + } + + private fun escapeCharForQuotedLiteral(c: Char) = + when(c) { + '\r' -> "\\r" + '\n' -> "\\n" + '\t' -> "\\t" + '\\' -> "\\\\" + '"' -> "\\\"" + else -> c.toString() + } + + // Render a string literal as it might occur in Kotlin source. Note this is a reasonable guess; the real source + // could use other escape sequences to describe the same String. Importantly, this is the same guess the Java + // extractor makes regarding string literals occurring within annotations, which we need to coincide with to ensure + // database consistency. + private fun toQuotedLiteral(s: String) = + s.toCharArray().joinToString(separator = "", prefix = "\"", postfix = "\"") { c -> escapeCharForQuotedLiteral(c) } + + private fun extractConstant( + e: IrConst<*>, + parent: Label, + idx: Int, + enclosingCallable: Label?, + enclosingStmt: Label?, + overrideId: Label? = null + ): Label? { + + val v = e.value + return when { + v is Number && (v is Int || v is Short || v is Byte) -> { + extractConstantInteger(v, tw.getLocation(e), parent, idx, enclosingCallable, enclosingStmt, overrideId = overrideId) + } + v is Long -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_longliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(v.toString(), v.toString(), id) + } + } + v is Float -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_floatingpointliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(v.toString(), v.toString(), id) + } + } + v is Double -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_doubleliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(v.toString(), v.toString(), id) + } + } + v is Boolean -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_booleanliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(v.toString(), v.toString(), id) + } + } + v is Char -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_characterliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(v.toString(), v.toString(), id) + } + } + v is String -> { + exprIdOrFresh(overrideId).also { id -> + val type = useType(e.type) + val locId = tw.getLocation(e) + tw.writeExprs_stringliteral(id, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + extractExprContext(id, locId, enclosingCallable, enclosingStmt) + tw.writeNamestrings(toQuotedLiteral(v.toString()), v.toString(), id) + } + } + v == null -> { + extractNull(e.type, tw.getLocation(e), parent, idx, enclosingCallable, enclosingStmt, overrideId = overrideId) + } + else -> { + null.also { + logger.errorElement("Unrecognised IrConst: " + v.javaClass, e) + } + } + } + } + private fun IrValueParameter.isExtensionReceiver(): Boolean { val parentFun = parent as? IrFunction ?: return false return parentFun.extensionReceiverParameter == this @@ -4164,12 +4503,12 @@ open class KotlinFileExtractor( val firstAssignmentStmtIdx = 1 if (dispatchReceiverInfo != null) { - extractField(dispatchReceiverInfo.field, "", dispatchReceiverInfo.type, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true) + extractField(dispatchReceiverInfo.field, "", dispatchReceiverInfo.type, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true, isStatic = false) extractParameterToFieldAssignmentInConstructor("", dispatchReceiverInfo.type, dispatchReceiverInfo.field, 0 + dispatchReceiverInfo.indexOffset, firstAssignmentStmtIdx + dispatchReceiverInfo.indexOffset) } if (extensionReceiverInfo != null) { - extractField(extensionReceiverInfo.field, "", extensionReceiverInfo.type, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true) + extractField(extensionReceiverInfo.field, "", extensionReceiverInfo.type, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true, isStatic = false) extractParameterToFieldAssignmentInConstructor( "", extensionReceiverInfo.type, extensionReceiverInfo.field, 0 + extensionReceiverInfo.indexOffset, firstAssignmentStmtIdx + extensionReceiverInfo.indexOffset) } } @@ -4393,6 +4732,8 @@ open class KotlinFileExtractor( } } + private val propertyRefType by lazy { referenceExternalClass("kotlin.jvm.internal.PropertyReference")?.typeWith() } + private fun extractPropertyReference( exprKind: String, propertyReferenceExpr: IrCallableReference, @@ -4456,8 +4797,7 @@ open class KotlinFileExtractor( val declarationParent = peekDeclStackAsDeclarationParent(propertyReferenceExpr) ?: return // The base class could be `Any`. `PropertyReference` is used to keep symmetry with function references. - val baseClass = pluginContext.referenceClass(FqName("kotlin.jvm.internal.PropertyReference"))?.owner?.typeWith() - ?: pluginContext.irBuiltIns.anyType + val baseClass = propertyRefType ?: pluginContext.irBuiltIns.anyType val classId = extractGeneratedClass(ids, listOf(baseClass, kPropertyType), locId, propertyReferenceExpr, declarationParent) @@ -4551,6 +4891,8 @@ open class KotlinFileExtractor( } } + private val functionRefType by lazy { referenceExternalClass("kotlin.jvm.internal.FunctionReference")?.typeWith() } + private fun extractFunctionReference( functionReferenceExpr: IrFunctionReference, parent: StmtExprParent, @@ -4665,10 +5007,9 @@ open class KotlinFileExtractor( } else { val declarationParent = peekDeclStackAsDeclarationParent(functionReferenceExpr) ?: return // `FunctionReference` base class is required, because that's implementing `KFunction`. - val baseClass = pluginContext.referenceClass(FqName("kotlin.jvm.internal.FunctionReference"))?.owner?.typeWith() - ?: pluginContext.irBuiltIns.anyType + val baseClass = functionRefType ?: pluginContext.irBuiltIns.anyType - val classId = extractGeneratedClass(ids, listOf(baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent, { it.valueParameters.size == 1 }) { + val classId = extractGeneratedClass(ids, listOf(baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent, null, { it.valueParameters.size == 1 }) { // The argument to FunctionReference's constructor is the function arity. extractConstantInteger(type.arguments.size - 1, locId, it, 0, ids.constructor, it) } @@ -4712,34 +5053,14 @@ open class KotlinFileExtractor( } } - private fun getFunctionalInterfaceType(functionNTypeArguments: List): IrSimpleType? { - if (functionNTypeArguments.size > BuiltInFunctionArity.BIG_ARITY) { - val funName = "kotlin.jvm.functions.FunctionN" - val theFun = pluginContext.referenceClass(FqName(funName)) - if (theFun == null) { - logger.warn("Cannot find $funName for getFunctionalInterfaceType") - return null - } else { - return theFun.typeWith(functionNTypeArguments.last()) - } - } else { - return functionN(pluginContext)(functionNTypeArguments.size - 1).typeWith(functionNTypeArguments) - } - } + private fun getFunctionalInterfaceType(functionNTypeArguments: List) = + getFunctionalInterfaceTypeWithTypeArgs(functionNTypeArguments.map { makeTypeProjection(it, Variance.INVARIANT) }) - private fun getFunctionalInterfaceTypeWithTypeArgs(functionNTypeArguments: List): IrSimpleType? = - if (functionNTypeArguments.size > BuiltInFunctionArity.BIG_ARITY) { - val funName = "kotlin.jvm.functions.FunctionN" - val theFun = pluginContext.referenceClass(FqName(funName)) - if (theFun == null) { - logger.warn("Cannot find $funName for getFunctionalInterfaceTypeWithTypeArgs") - null - } else { - theFun.typeWithArguments(listOf(functionNTypeArguments.last())) - } - } else { + private fun getFunctionalInterfaceTypeWithTypeArgs(functionNTypeArguments: List) = + if (functionNTypeArguments.size > BuiltInFunctionArity.BIG_ARITY) + referenceExternalClass("kotlin.jvm.functions.FunctionN")?.symbol?.typeWithArguments(listOf(functionNTypeArguments.last())) + else functionN(pluginContext)(functionNTypeArguments.size - 1).symbol.typeWithArguments(functionNTypeArguments) - } private data class FunctionLabels( val methodId: Label, @@ -4945,11 +5266,11 @@ open class KotlinFileExtractor( /** * Extracts a single type access expression with no enclosing callable and statement. */ - private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { + private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int, overrideId: Label? = null): Label { // TODO: elementForLocation allows us to give some sort of // location, but a proper location for the type access will // require upstream changes - val id = tw.getFreshIdLabel() + val id = exprIdOrFresh(overrideId) tw.writeExprs_unannotatedtypeaccess(id, type.javaResult.id, parent, idx) tw.writeExprsKotlinType(id, type.kotlinResult.id) tw.writeHasLocation(id, location) @@ -4959,10 +5280,14 @@ open class KotlinFileExtractor( /** * Extracts a single type access expression with enclosing callable and statement. */ - private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int, enclosingCallable: Label, enclosingStmt: Label): Label { - val id = extractTypeAccess(type, location, parent, idx) - tw.writeCallableEnclosingExpr(id, enclosingCallable) - tw.writeStatementEnclosingExpr(id, enclosingStmt) + private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int, enclosingCallable: Label?, enclosingStmt: Label?, overrideId: Label? = null): Label { + val id = extractTypeAccess(type, location, parent, idx, overrideId = overrideId) + if (enclosingCallable != null) { + tw.writeCallableEnclosingExpr(id, enclosingCallable) + } + if (enclosingStmt != null) { + tw.writeStatementEnclosingExpr(id, enclosingStmt) + } return id } @@ -5004,11 +5329,14 @@ open class KotlinFileExtractor( /** * Extracts a type access expression and its child type access expressions in case of a generic type. Nested generics are also handled. */ - private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, enclosingCallable: Label, enclosingStmt: Label, typeContext: TypeContext = TypeContext.OTHER): Label { + private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, enclosingCallable: Label?, enclosingStmt: Label?, typeContext: TypeContext = TypeContext.OTHER, overrideId: Label? = null): Label { // TODO: `useType` substitutes types to their java equivalent, and sometimes that also means changing the number of type arguments. The below logic doesn't take this into account. // For example `KFunction2` becomes `KFunction` with three child type access expressions: `Int`, `Double`, `String`. - val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx, enclosingCallable, enclosingStmt) + val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx, enclosingCallable, enclosingStmt, overrideId = overrideId) if (t is IrSimpleType) { + if (t.arguments.isNotEmpty() && overrideId != null) { + logger.error("Unexpected parameterized type with an overridden expression ID; children will be assigned fresh IDs") + } extractTypeArguments(t.arguments.filterIsInstance(), location, typeAccessId, enclosingCallable, enclosingStmt) } return typeAccessId @@ -5022,8 +5350,8 @@ open class KotlinFileExtractor( typeArgs: List, location: Label, parentExpr: Label, - enclosingCallable: Label, - enclosingStmt: Label, + enclosingCallable: Label?, + enclosingStmt: Label?, startIndex: Int = 0, reverse: Boolean = false ) { @@ -5237,7 +5565,7 @@ open class KotlinFileExtractor( // add field val fieldId = tw.getFreshIdLabel() - extractField(fieldId, "", functionType, classId, locId, DescriptorVisibilities.PRIVATE, e, isExternalDeclaration = false, isFinal = true) + extractField(fieldId, "", functionType, classId, locId, DescriptorVisibilities.PRIVATE, e, isExternalDeclaration = false, isFinal = true, isStatic = false) // adjust constructor helper.extractParameterToFieldAssignmentInConstructor("", functionType, fieldId, 0, 1) @@ -5256,7 +5584,7 @@ open class KotlinFileExtractor( // we would need to compose generic type substitutions -- for example, if we're implementing // T UnaryOperator.apply(T t) here, we would need to compose substitutions so we can implement // the real underlying R Function.apply(T t). - forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e))) + forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, extractAnnotations = false, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e), modality = Modality.FINAL)) addModifiers(ids.function, "override") if (st.isSuspendFunctionOrKFunction()) { @@ -5372,13 +5700,15 @@ open class KotlinFileExtractor( locId: Label, elementToReportOn: IrElement, declarationParent: IrDeclarationParent, + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null, superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() }, - extractSuperconstructorArgs: (Label) -> Unit = {} + extractSuperconstructorArgs: (Label) -> Unit = {}, ): Label { // Write class val id = ids.type.javaResult.id.cast() val pkgId = extractPackage("") tw.writeClasses(id, "", pkgId, id) + tw.writeCompiler_generated(id, (compilerGeneratedKindOverride ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind) tw.writeHasLocation(id, locId) // Extract constructor @@ -5425,14 +5755,18 @@ open class KotlinFileExtractor( /** * Extracts the class around a local function or a lambda. The superclass must have a no-arg constructor. */ - private fun extractGeneratedClass(localFunction: IrFunction, superTypes: List) : Label { + private fun extractGeneratedClass( + localFunction: IrFunction, + superTypes: List, + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null + ) : Label { with("generated class", localFunction) { val ids = getLocallyVisibleFunctionLabels(localFunction) - val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent) + val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent, compilerGeneratedKindOverride = compilerGeneratedKindOverride) // Extract local function as a member - extractFunction(localFunction, id, extractBody = true, extractMethodAndParameterTypeAccesses = true, null, listOf()) + extractFunction(localFunction, id, extractBody = true, extractMethodAndParameterTypeAccesses = true, extractAnnotations = false, null, listOf()) return id } @@ -5475,6 +5809,7 @@ open class KotlinFileExtractor( val typeParameters: List? = null, val isStatic: Boolean? = null, val visibility: DescriptorVisibility? = null, + val modality: Modality? = null, ) private fun peekDeclStackAsDeclarationParent(elementToReportOn: IrElement): IrDeclarationParent? { @@ -5503,5 +5838,6 @@ open class KotlinFileExtractor( DEFAULT_ARGUMENTS_METHOD(10), INTERFACE_FORWARDER(11), ENUM_CONSTRUCTOR_ARGUMENT(12), + CALLABLE_CLASS(13), } } diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index b9e66ac18d6..cc335d3f8cb 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -40,11 +40,15 @@ open class KotlinUsesExtractor( val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState ) { - val javaLangObject by lazy { - val result = pluginContext.referenceClass(FqName("java.lang.Object"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + fun referenceExternalClass(name: String) = + pluginContext.referenceClass(FqName(name))?.owner.also { + if (it == null) + logger.warn("Unable to resolve external class $name") + else + extractExternalClassLater(it) + } + + val javaLangObject by lazy { referenceExternalClass("java.lang.Object") } val javaLangObjectType by lazy { javaLangObject?.typeWith() @@ -67,15 +71,12 @@ open class KotlinUsesExtractor( TypeResult(fakeKotlinType(), "", "") ) - @OptIn(kotlin.ExperimentalStdlibApi::class) // Annotation required by kotlin versions < 1.5 fun extractFileClass(f: IrFile): Label { - val fileName = f.fileEntry.name val pkg = f.fqName.asString() - val defaultName = fileName.replaceFirst(Regex(""".*[/\\]"""), "").replaceFirst(Regex("""\.kt$"""), "").replaceFirstChar({ it.uppercase() }) + "Kt" - var jvmName = getJvmName(f) ?: defaultName + val jvmName = getFileClassName(f) val qualClassName = if (pkg.isEmpty()) jvmName else "$pkg.$jvmName" val label = "@\"class;$qualClassName\"" - val id: Label = tw.getLabelFor(label, { + val id: Label = tw.getLabelFor(label) { val fileId = tw.mkFileId(f.path, false) val locId = tw.getWholeFileLocation(fileId) val pkgId = extractPackage(pkg) @@ -84,7 +85,7 @@ open class KotlinUsesExtractor( tw.writeHasLocation(it, locId) addModifiers(it, "public", "final") - }) + } return id } @@ -258,10 +259,26 @@ open class KotlinUsesExtractor( private fun propertySignature(p: IrProperty) = ((p.getter ?: p.setter)?.extensionReceiverParameter?.let { useType(erase(it.type)).javaResult.signature } ?: "") + fun getTrapFileSignature(d: IrDeclaration) = + when(d) { + is IrFunction -> + // Note we erase the parameter types before calling useType even though the signature should be the same + // in order to prevent an infinite loop through useTypeParameter -> useDeclarationParent -> useFunction + // -> extractFunctionLaterIfExternalFileMember, which would result for `fun f(t: T) { ... }` for example. + (listOfNotNull(d.extensionReceiverParameter) + d.valueParameters) + .map { useType(erase(it.type)).javaResult.signature } + .joinToString(separator = ",", prefix = "(", postfix = ")") + is IrProperty -> propertySignature(d) + externalClassExtractor.propertySignature + is IrField -> (d.correspondingPropertySymbol?.let { propertySignature(it.owner) } ?: "") + externalClassExtractor.fieldSignature + else -> "unknown signature".also { + logger.warn("Trap file signature requested for unexpected element $d") + } + } + private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) { if (isExternalFileClassMember(p)) { extractExternalClassLater(p.parentAsClass) - val signature = propertySignature(p) + externalClassExtractor.propertySignature + val signature = getTrapFileSignature(p) dependencyCollector?.addDependency(p, signature) externalClassExtractor.extractLater(p, signature) } @@ -270,7 +287,7 @@ open class KotlinUsesExtractor( private fun extractFieldLaterIfExternalFileMember(f: IrField) { if (isExternalFileClassMember(f)) { extractExternalClassLater(f.parentAsClass) - val signature = (f.correspondingPropertySymbol?.let { propertySignature(it.owner) } ?: "") + externalClassExtractor.fieldSignature + val signature = getTrapFileSignature(f) dependencyCollector?.addDependency(f, signature) externalClassExtractor.extractLater(f, signature) } @@ -285,18 +302,7 @@ open class KotlinUsesExtractor( // getters and setters are extracted alongside it return } - // Note we erase the parameter types before calling useType even though the signature should be the same - // in order to prevent an infinite loop through useTypeParameter -> useDeclarationParent -> useFunction - // -> extractFunctionLaterIfExternalFileMember, which would result for `fun f(t: T) { ... }` for example. - val ext = f.extensionReceiverParameter - val parameters = if (ext != null) { - listOf(ext) + f.valueParameters - } else { - f.valueParameters - } - - val paramSigs = parameters.map { useType(erase(it.type)).javaResult.signature } - val signature = paramSigs.joinToString(separator = ",", prefix = "(", postfix = ")") + val signature = getTrapFileSignature(f) dependencyCollector?.addDependency(f, signature) externalClassExtractor.extractLater(f, signature) } @@ -821,7 +827,7 @@ open class KotlinUsesExtractor( OperatorNameConventions.INVOKE.asString()) fun getSuffixIfInternal() = - if (f.visibility == DescriptorVisibilities.INTERNAL && f !is IrConstructor) { + if (f.visibility == DescriptorVisibilities.INTERNAL && f !is IrConstructor && !(f.parent is IrFile || isExternalFileClassMember(f))) { "\$" + getJvmModuleName(f) } else { "" @@ -883,11 +889,7 @@ open class KotlinUsesExtractor( else -> null } - val javaUtilCollection by lazy { - val result = pluginContext.referenceClass(FqName("java.util.Collection"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val javaUtilCollection by lazy { referenceExternalClass("java.util.Collection") } val wildcardCollectionType by lazy { javaUtilCollection?.let { @@ -1150,11 +1152,7 @@ open class KotlinUsesExtractor( return "@\"$prefix;{$parentId}.$name($paramTypeIds){$returnTypeId}${typeArgSuffix}\"" } - val javaLangClass by lazy { - val result = pluginContext.referenceClass(FqName("java.lang.Class"))?.owner - result?.let { extractExternalClassLater(it) } - result - } + val javaLangClass by lazy { referenceExternalClass("java.lang.Class") } fun kClassToJavaClass(t: IrType): IrType { when(t) { @@ -1647,7 +1645,7 @@ open class KotlinUsesExtractor( fun useValueParameter(vp: IrValueParameter, parent: Label?): Label = tw.getLabelFor(getValueParameterLabel(vp, parent)) - private fun isDirectlyExposedCompanionObjectField(f: IrField) = + private fun isDirectlyExposableCompanionObjectField(f: IrField) = f.hasAnnotation(FqName("kotlin.jvm.JvmField")) || f.correspondingPropertySymbol?.owner?.let { it.isConst || it.isLateinit @@ -1655,12 +1653,14 @@ open class KotlinUsesExtractor( fun getFieldParent(f: IrField) = f.parentClassOrNull?.let { - if (it.isCompanion && isDirectlyExposedCompanionObjectField(f)) + if (it.isCompanion && isDirectlyExposableCompanionObjectField(f)) it.parent else null } ?: f.parent + fun isDirectlyExposedCompanionObjectField(f: IrField) = getFieldParent(f) != f.parent + // Gets a field's corresponding property's extension receiver type, if any fun getExtensionReceiverType(f: IrField) = f.correspondingPropertySymbol?.owner?.let { diff --git a/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt b/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt index 45e23498e9d..27b62c86109 100644 --- a/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt +++ b/java/kotlin-extractor/src/main/kotlin/LinesOfCode.kt @@ -16,7 +16,7 @@ class LinesOfCode( val tw: FileTrapWriter, val file: IrFile ) { - val psi2Ir = getPsi2Ir(logger).also { + val psi2Ir = getPsi2Ir().also { if (it == null) { logger.warn("Lines of code will not be populated as Kotlin version is too old (${KotlinCompilerVersion.getVersion()})") } diff --git a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt new file mode 100644 index 00000000000..5fdf073813d --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt @@ -0,0 +1,396 @@ +package com.github.codeql + +import com.github.codeql.utils.versions.copyParameterToFunction +import com.github.codeql.utils.versions.createImplicitParameterDeclarationWithWrappedDescriptor +import com.github.codeql.utils.versions.getAnnotationType +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention +import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.declarations.addConstructor +import org.jetbrains.kotlin.ir.builders.declarations.addGetter +import org.jetbrains.kotlin.ir.builders.declarations.addProperty +import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter +import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.builders.declarations.buildField +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrEnumEntry +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.expressions.IrClassReference +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue +import org.jetbrains.kotlin.ir.expressions.IrVararg +import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.types.typeWith +import org.jetbrains.kotlin.ir.util.constructedClass +import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.ir.util.getAnnotation +import org.jetbrains.kotlin.ir.util.hasAnnotation +import org.jetbrains.kotlin.ir.util.hasEqualFqName +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.primaryConstructor +import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import java.lang.annotation.ElementType +import java.util.HashSet + +class MetaAnnotationSupport(private val logger: FileLogger, private val pluginContext: IrPluginContext, private val extractor: KotlinFileExtractor) { + + // Taken from AdditionalIrUtils.kt (not available in Kotlin < 1.6) + private val IrConstructorCall.annotationClass + get() = this.symbol.owner.constructedClass + + // Taken from AdditionalIrUtils.kt (not available in Kotlin < 1.6) + private fun IrConstructorCall.isAnnotationWithEqualFqName(fqName: FqName): Boolean = + annotationClass.hasEqualFqName(fqName) + + // Adapted from RepeatedAnnotationLowering.kt + fun groupRepeatableAnnotations(annotations: List): List { + if (annotations.size < 2) return annotations + + val annotationsByClass = annotations.groupByTo(mutableMapOf()) { it.annotationClass } + if (annotationsByClass.values.none { it.size > 1 }) return annotations + + val result = mutableListOf() + for (annotation in annotations) { + val annotationClass = annotation.annotationClass + val grouped = annotationsByClass.remove(annotationClass) ?: continue + if (grouped.size < 2) { + result.add(grouped.single()) + continue + } + + val containerClass = getOrCreateContainerClass(annotationClass) + if (containerClass != null) + wrapAnnotationEntriesInContainer(annotationClass, containerClass, grouped)?.let { + result.add(it) + } + else + logger.warnElement("Failed to find an annotation container class", annotationClass) + } + return result + } + + // Adapted from RepeatedAnnotationLowering.kt + private fun getOrCreateContainerClass(annotationClass: IrClass): IrClass? { + val metaAnnotations = annotationClass.annotations + val jvmRepeatable = metaAnnotations.find { it.symbol.owner.parentAsClass.fqNameWhenAvailable == JvmAnnotationNames.REPEATABLE_ANNOTATION } + return if (jvmRepeatable != null) { + ((jvmRepeatable.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol)?.owner + } else { + getOrCreateSyntheticRepeatableAnnotationContainer(annotationClass) + } + } + + // Adapted from RepeatedAnnotationLowering.kt + private fun wrapAnnotationEntriesInContainer( + annotationClass: IrClass, + containerClass: IrClass, + entries: List + ): IrConstructorCall? { + val annotationType = annotationClass.typeWith() + val containerConstructor = containerClass.primaryConstructor + if (containerConstructor == null) { + logger.warnElement("Expected container class to have a primary constructor", containerClass) + return null + } else { + return IrConstructorCallImpl.fromSymbolOwner(containerClass.defaultType, containerConstructor.symbol).apply { + putValueArgument( + 0, + IrVarargImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + pluginContext.irBuiltIns.arrayClass.typeWith(annotationType), + annotationType, + entries + ) + ) + } + } + } + + // Taken from AdditionalClassAnnotationLowering.kt + private fun getApplicableTargetSet(c: IrClass): Set? { + val targetEntry = c.getAnnotation(StandardNames.FqNames.target) ?: return null + return loadAnnotationTargets(targetEntry) + } + + // Taken from AdditionalClassAnnotationLowering.kt + private fun loadAnnotationTargets(targetEntry: IrConstructorCall): Set? { + val valueArgument = targetEntry.getValueArgument(0) as? IrVararg ?: return null + return valueArgument.elements.filterIsInstance().mapNotNull { + KotlinTarget.valueOrNull(it.symbol.owner.name.asString()) + }.toSet() + } + + private val javaAnnotationTargetElementType by lazy { extractor.referenceExternalClass("java.lang.annotation.ElementType") } + + private val javaAnnotationTarget by lazy { extractor.referenceExternalClass("java.lang.annotation.Target") } + + private fun findEnumEntry(c: IrClass, name: String) = + c.declarations.filterIsInstance().find { it.name.asString() == name } + + // Adapted from JvmSymbols.kt + private val jvm6TargetMap by lazy { + javaAnnotationTargetElementType?.let { + val etMethod = findEnumEntry(it, "METHOD") + mapOf( + KotlinTarget.CLASS to findEnumEntry(it, "TYPE"), + KotlinTarget.ANNOTATION_CLASS to findEnumEntry(it, "ANNOTATION_TYPE"), + KotlinTarget.CONSTRUCTOR to findEnumEntry(it, "CONSTRUCTOR"), + KotlinTarget.LOCAL_VARIABLE to findEnumEntry(it, "LOCAL_VARIABLE"), + KotlinTarget.FUNCTION to etMethod, + KotlinTarget.PROPERTY_GETTER to etMethod, + KotlinTarget.PROPERTY_SETTER to etMethod, + KotlinTarget.FIELD to findEnumEntry(it, "FIELD"), + KotlinTarget.VALUE_PARAMETER to findEnumEntry(it, "PARAMETER") + ) + } + } + + // Adapted from JvmSymbols.kt + private val jvm8TargetMap by lazy { + javaAnnotationTargetElementType?.let { + jvm6TargetMap?.let { j6Map -> + j6Map + mapOf( + KotlinTarget.TYPE_PARAMETER to findEnumEntry(it, "TYPE_PARAMETER"), + KotlinTarget.TYPE to findEnumEntry(it, "TYPE_USE") + ) + } + } + } + + private fun getAnnotationTargetMap() = + if (pluginContext.platform?.any { it.targetPlatformVersion == JvmTarget.JVM_1_6 } == true) + jvm6TargetMap + else + jvm8TargetMap + + // Adapted from AdditionalClassAnnotationLowering.kt + private fun generateTargetAnnotation(c: IrClass): IrConstructorCall? { + if (c.hasAnnotation(JvmAnnotationNames.TARGET_ANNOTATION)) + return null + val elementType = javaAnnotationTargetElementType ?: return null + val targetType = javaAnnotationTarget ?: return null + val targetConstructor = targetType.declarations.firstIsInstanceOrNull() ?: return null + val targets = getApplicableTargetSet(c) ?: return null + val annotationTargetMap = getAnnotationTargetMap() ?: return null + + val javaTargets = targets.mapNotNullTo(HashSet()) { annotationTargetMap[it] }.sortedBy { + ElementType.valueOf(it.symbol.owner.name.asString()) + } + val vararg = IrVarargImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + type = pluginContext.irBuiltIns.arrayClass.typeWith(elementType.defaultType), + varargElementType = elementType.defaultType + ) + for (target in javaTargets) { + vararg.elements.add( + IrGetEnumValueImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, elementType.defaultType, target.symbol + ) + ) + } + + return IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, targetConstructor.symbol, 0 + ).apply { + putValueArgument(0, vararg) + } + } + + private val javaAnnotationRetention by lazy { extractor.referenceExternalClass("java.lang.annotation.Retention") } + private val javaAnnotationRetentionPolicy by lazy { extractor.referenceExternalClass("java.lang.annotation.RetentionPolicy") } + private val javaAnnotationRetentionPolicyRuntime by lazy { javaAnnotationRetentionPolicy?.let { findEnumEntry(it, "RUNTIME") } } + + private val annotationRetentionMap by lazy { + javaAnnotationRetentionPolicy?.let { + mapOf( + KotlinRetention.SOURCE to findEnumEntry(it, "SOURCE"), + KotlinRetention.BINARY to findEnumEntry(it, "CLASS"), + KotlinRetention.RUNTIME to javaAnnotationRetentionPolicyRuntime + ) + } + } + + // Taken from AnnotationCodegen.kt (not available in Kotlin < 1.6.20) + private fun IrClass.getAnnotationRetention(): KotlinRetention? { + val retentionArgument = + getAnnotation(StandardNames.FqNames.retention)?.getValueArgument(0) + as? IrGetEnumValue ?: return null + val retentionArgumentValue = retentionArgument.symbol.owner + return KotlinRetention.valueOf(retentionArgumentValue.name.asString()) + } + + // Taken from AdditionalClassAnnotationLowering.kt + private fun generateRetentionAnnotation(irClass: IrClass): IrConstructorCall? { + if (irClass.hasAnnotation(JvmAnnotationNames.RETENTION_ANNOTATION)) + return null + val retentionMap = annotationRetentionMap ?: return null + val kotlinRetentionPolicy = irClass.getAnnotationRetention() + val javaRetentionPolicy = kotlinRetentionPolicy?.let { retentionMap[it] } ?: javaAnnotationRetentionPolicyRuntime ?: return null + val retentionPolicyType = javaAnnotationRetentionPolicy ?: return null + val retentionType = javaAnnotationRetention ?: return null + val targetConstructor = retentionType.declarations.firstIsInstanceOrNull() ?: return null + + return IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, targetConstructor.symbol, 0 + ).apply { + putValueArgument( + 0, + IrGetEnumValueImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, retentionPolicyType.defaultType, javaRetentionPolicy.symbol + ) + ) + } + } + + private val javaAnnotationRepeatable by lazy { extractor.referenceExternalClass("java.lang.annotation.Repeatable") } + private val kotlinAnnotationRepeatableContainer by lazy { extractor.referenceExternalClass("kotlin.jvm.internal.RepeatableContainer") } + + // Taken from declarationBuilders.kt (not available in Kotlin < 1.6): + private fun addDefaultGetter(p: IrProperty, parentClass: IrClass) { + val field = p.backingField ?: + run { logger.warnElement("Expected property to have a backing field", p); return } + p.addGetter { + origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR + returnType = field.type + }.apply { + val thisReceiever = parentClass.thisReceiver ?: + run { logger.warnElement("Expected property's parent class to have a receiver parameter", parentClass); return } + val newParam = copyParameterToFunction(thisReceiever, this) + dispatchReceiverParameter = newParam + body = factory.createBlockBody( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( + IrReturnImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + pluginContext.irBuiltIns.nothingType, + symbol, + IrGetFieldImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + field.symbol, + field.type, + IrGetValueImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + newParam.type, + newParam.symbol + ) + ) + ) + ) + ) + } + } + + // Taken from JvmCachedDeclarations.kt + private fun getOrCreateSyntheticRepeatableAnnotationContainer(annotationClass: IrClass) = + extractor.globalExtensionState.syntheticRepeatableAnnotationContainers.getOrPut(annotationClass) { + val containerClass = pluginContext.irFactory.buildClass { + kind = ClassKind.ANNOTATION_CLASS + name = Name.identifier("Container") + }.apply { + createImplicitParameterDeclarationWithWrappedDescriptor() + parent = annotationClass + superTypes = listOf(getAnnotationType(pluginContext)) + } + + val propertyName = Name.identifier("value") + val propertyType = pluginContext.irBuiltIns.arrayClass.typeWith(annotationClass.typeWith()) + + containerClass.addConstructor { + isPrimary = true + }.apply { + addValueParameter(propertyName.identifier, propertyType) + } + + containerClass.addProperty { + name = propertyName + }.apply property@{ + backingField = pluginContext.irFactory.buildField { + name = propertyName + type = propertyType + }.apply { + parent = containerClass + correspondingPropertySymbol = this@property.symbol + } + addDefaultGetter(this, containerClass) + } + + val repeatableContainerAnnotation = kotlinAnnotationRepeatableContainer?.constructors?.single() + + containerClass.annotations = annotationClass.annotations + .filter { + it.isAnnotationWithEqualFqName(StandardNames.FqNames.retention) || + it.isAnnotationWithEqualFqName(StandardNames.FqNames.target) + } + .map { it.deepCopyWithSymbols(containerClass) } + + listOfNotNull( + repeatableContainerAnnotation?.let { + IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.returnType, it.symbol, 0 + ) + } + ) + + containerClass + } + + // Adapted from AdditionalClassAnnotationLowering.kt + private fun generateRepeatableAnnotation(irClass: IrClass, extractAnnotationTypeAccesses: Boolean): IrConstructorCall? { + if (!irClass.hasAnnotation(StandardNames.FqNames.repeatable) || + irClass.hasAnnotation(JvmAnnotationNames.REPEATABLE_ANNOTATION) + ) return null + + val repeatableConstructor = javaAnnotationRepeatable?.declarations?.firstIsInstanceOrNull() ?: return null + + val containerClass = getOrCreateSyntheticRepeatableAnnotationContainer(irClass) + // Whenever a repeatable annotation with a Kotlin-synthesised container is extracted, extract the synthetic container to the same trap file. + extractor.extractClassSource(containerClass, extractDeclarations = true, extractStaticInitializer = true, extractPrivateMembers = true, extractFunctionBodies = extractAnnotationTypeAccesses) + + val containerReference = IrClassReferenceImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, pluginContext.irBuiltIns.kClassClass.typeWith(containerClass.defaultType), + containerClass.symbol, containerClass.defaultType + ) + return IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, repeatableConstructor.returnType, repeatableConstructor.symbol, 0 + ).apply { + putValueArgument(0, containerReference) + } + } + + private val javaAnnotationDocumented by lazy { extractor.referenceExternalClass("java.lang.annotation.Documented") } + + // Taken from AdditionalClassAnnotationLowering.kt + private fun generateDocumentedAnnotation(irClass: IrClass): IrConstructorCall? { + if (!irClass.hasAnnotation(StandardNames.FqNames.mustBeDocumented) || + irClass.hasAnnotation(JvmAnnotationNames.DOCUMENTED_ANNOTATION) + ) return null + + val documentedConstructor = javaAnnotationDocumented?.declarations?.firstIsInstanceOrNull() ?: return null + + return IrConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, documentedConstructor.returnType, documentedConstructor.symbol, 0 + ) + } + + fun generateJavaMetaAnnotations(c: IrClass, extractAnnotationTypeAccesses: Boolean) = + // This is essentially AdditionalClassAnnotationLowering adapted to run outside the backend. + listOfNotNull(generateTargetAnnotation(c), generateRetentionAnnotation(c), generateRepeatableAnnotation(c, extractAnnotationTypeAccesses), generateDocumentedAnnotation(c)) +} + diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index 310eb3e18b0..ad4aaf60936 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -25,7 +25,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v private val logger = fileExtractor.logger fun extract() { - val psi2Ir = getPsi2Ir(logger) + val psi2Ir = getPsi2Ir() if (psi2Ir == null) { logger.warn("Comments will not be extracted as Kotlin version is too old (${KotlinCompilerVersion.getVersion()})") return diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt index 15ca35a1438..ab4010242a7 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.parentClassOrNull @@ -21,20 +22,46 @@ import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource // for `that`. private fun getName(d: IrDeclarationWithName) = (d as? IrAnnotationContainer)?.let { getJvmName(it) } ?: d.name.asString() -fun getIrDeclBinaryName(that: IrDeclaration): String { - val shortName = when(that) { - is IrDeclarationWithName -> getName(that) - else -> "(unknown-name)" - } - val internalName = StringBuilder(shortName); - generateSequence(that.parent) { (it as? IrDeclaration)?.parent } - .forEach { - when (it) { - is IrClass -> internalName.insert(0, getName(it) + "$") - is IrPackageFragment -> it.fqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") } - } - } - return internalName.toString() +@OptIn(ExperimentalStdlibApi::class) // Annotation required by kotlin versions < 1.5 +fun getFileClassName(f: IrFile) = + getJvmName(f) ?: + ((f.fileEntry.name.replaceFirst(Regex(""".*[/\\]"""), "") + .replaceFirst(Regex("""\.kt$"""), "") + .replaceFirstChar { it.uppercase() }) + "Kt") + +fun getIrElementBinaryName(that: IrElement): String { + if (that is IrFile) { + val shortName = getFileClassName(that) + val pkg = that.fqName.asString() + return if (pkg.isEmpty()) shortName else "$pkg.$shortName" + } + + if (that !is IrDeclaration) { + return "(unknown-name)" + } + + val shortName = when(that) { + is IrDeclarationWithName -> getName(that) + else -> "(unknown-name)" + } + + val internalName = StringBuilder(shortName) + if (that !is IrClass) { + val parent = that.parent + if (parent is IrFile) { + // Note we'll fall through and do the IrPackageFragment case as well, since IrFile <: IrPackageFragment + internalName.insert(0, getFileClassName(parent) + "$") + } + } + + generateSequence(that.parent) { (it as? IrDeclaration)?.parent } + .forEach { + when (it) { + is IrClass -> internalName.insert(0, getName(it) + "$") + is IrPackageFragment -> it.fqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") } + } + } + return internalName.toString() } fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? { @@ -81,7 +108,7 @@ private fun getRawIrClassBinaryPath(irClass: IrClass) = fun getIrClassBinaryPath(irClass: IrClass): String { return getRawIrClassBinaryPath(irClass) // Otherwise, make up a fake location: - ?: "/!unknown-binary-location/${getIrDeclBinaryName(irClass).replace(".", "/")}.class" + ?: "/!unknown-binary-location/${getIrElementBinaryName(irClass).replace(".", "/")}.class" } fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? { diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 43c6ee4cc10..3b66e527429 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -10,7 +10,7 @@ import java.util.Stack import org.jetbrains.kotlin.ir.IrElement class LogCounter() { - public val diagnosticCounts = mutableMapOf() + public val diagnosticInfo = mutableMapOf>() public val diagnosticLimit: Int init { diagnosticLimit = System.getenv("CODEQL_EXTRACTOR_KOTLIN_DIAGNOSTIC_LIMIT")?.toIntOrNull() ?: 100 @@ -114,12 +114,23 @@ open class LoggerBase(val logCounter: LogCounter) { if(diagnosticLoc == null) { " Missing caller information.\n" } else { - val count = logCounter.diagnosticCounts.getOrDefault(diagnosticLoc, 0) + 1 - logCounter.diagnosticCounts[diagnosticLoc] = count + val oldInfo = logCounter.diagnosticInfo.getOrDefault(diagnosticLoc, Pair(severity, 0)) + if(severity != oldInfo.first) { + // We don't want to get in a loop, so just emit this + // directly without going through the diagnostic + // counting machinery + if (verbosity >= 1) { + val message = "Severity mismatch ($severity vs ${oldInfo.first}) at $diagnosticLoc" + emitDiagnostic(tw, Severity.Error, "Inconsistency", message, message) + } + } + val newCount = oldInfo.second + 1 + val newInfo = Pair(severity, newCount) + logCounter.diagnosticInfo[diagnosticLoc] = newInfo when { logCounter.diagnosticLimit <= 0 -> "" - count == logCounter.diagnosticLimit -> " Limit reached for diagnostics from $diagnosticLoc.\n" - count > logCounter.diagnosticLimit -> return + newCount == logCounter.diagnosticLimit -> " Limit reached for diagnostics from $diagnosticLoc.\n" + newCount > logCounter.diagnosticLimit -> return else -> "" } } @@ -138,6 +149,10 @@ open class LoggerBase(val logCounter: LogCounter) { fullMsgBuilder.append(suffix) val fullMsg = fullMsgBuilder.toString() + emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId) + } + + private fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label = { tw.unknownLocation }) { val locStr = if (locationString == null) "" else "At " + locationString + ": " val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR" val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg") @@ -185,14 +200,17 @@ open class LoggerBase(val logCounter: LogCounter) { } fun printLimitedDiagnosticCounts(tw: TrapWriter) { - for((caller, count) in logCounter.diagnosticCounts) { + for((caller, info) in logCounter.diagnosticInfo) { + val severity = info.first + val count = info.second if(count >= logCounter.diagnosticLimit) { // We don't know if this location relates to an error // or a warning, so we just declare hitting the limit // to be an error regardless. - val logMessage = LogMessage("ERROR", "Total of $count diagnostics from $caller.") - tw.writeComment(logMessage.toText()) - logStream.write(logMessage.toJsonLine()) + val message = "Total of $count diagnostics (reached limit of ${logCounter.diagnosticLimit}) from $caller." + if (verbosity >= 1) { + emitDiagnostic(tw, severity, "Limit", message, message) + } } } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt index 2990acfc98f..80120107478 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt @@ -1,5 +1,3 @@ package com.github.codeql.utils.versions -import com.github.codeql.FileLogger - -fun getPsi2Ir(@Suppress("UNUSED_PARAMETER") logger: FileLogger): Psi2IrFacade? = null +fun getPsi2Ir(): Psi2IrFacade? = null diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/annotationType.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/annotationType.kt new file mode 100644 index 00000000000..08fd0315f7c --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/annotationType.kt @@ -0,0 +1,8 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI + +@OptIn(ObsoleteDescriptorBasedAPI::class) +fun getAnnotationType(context: IrPluginContext) = + context.typeTranslator.translateType(context.builtIns.annotationType) \ No newline at end of file diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/copyTo.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/copyTo.kt new file mode 100644 index 00000000000..4147daa340f --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/copyTo.kt @@ -0,0 +1,7 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.backend.common.ir.copyTo + +fun copyParameterToFunction(p: IrValueParameter, f: IrFunction) = p.copyTo(f) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt index 024710bc4b8..73987106c55 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt @@ -1,6 +1,5 @@ package com.github.codeql.utils.versions -import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -8,9 +7,9 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -fun getPsi2Ir(logger: FileLogger): Psi2IrFacade? = Psi2Ir(logger) +fun getPsi2Ir(): Psi2IrFacade? = Psi2Ir() -private class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { +private class Psi2Ir(): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/annotationType.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/annotationType.kt new file mode 100644 index 00000000000..3ce3cad89ec --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/annotationType.kt @@ -0,0 +1,6 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext + +fun getAnnotationType(context: IrPluginContext) = + context.irBuiltIns.annotationType \ No newline at end of file diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/allOverriddenIncludingSelf.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/allOverriddenIncludingSelf.kt similarity index 100% rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/allOverriddenIncludingSelf.kt rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/allOverriddenIncludingSelf.kt diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/copyTo.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/copyTo.kt new file mode 100644 index 00000000000..701bd21036e --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/copyTo.kt @@ -0,0 +1,7 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.util.copyTo + +fun copyParameterToFunction(p: IrValueParameter, f: IrFunction) = p.copyTo(f) \ No newline at end of file diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/createImplicitParameterDeclarationWithWrappedDescriptor.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/createImplicitParameterDeclarationWithWrappedDescriptor.kt similarity index 100% rename from java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20-Beta/createImplicitParameterDeclarationWithWrappedDescriptor.kt rename to java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_20/createImplicitParameterDeclarationWithWrappedDescriptor.kt diff --git a/java/ql/consistency-queries/children.ql b/java/ql/consistency-queries/children.ql index 9401c8785e4..b22fd56d044 100644 --- a/java/ql/consistency-queries/children.ql +++ b/java/ql/consistency-queries/children.ql @@ -41,7 +41,12 @@ predicate gapInChildren(Element e, int i) { // -1 can be skipped (type arguments from -2 down, no qualifier at -1, // then arguments from 0). // Can we also skip arguments, e.g. due to defaults for parameters? - not (e instanceof MethodAccess and e.getFile().isKotlinSourceFile()) + not (e instanceof MethodAccess and e.getFile().isKotlinSourceFile()) and + // Kotlin-extracted annotations can have missing children where a default + // value should be, because kotlinc doesn't load annotation defaults and we + // want to leave a space for another extractor to fill in the default if it + // is able. + not e instanceof Annotation } predicate lateFirstChild(Element e, int i) { @@ -59,7 +64,12 @@ predicate lateFirstChild(Element e, int i) { not (e instanceof LocalVariableDeclStmt and i = 1 and not exists(nthChildOf(e, 2))) and // For statements may or may not declare a new variable (child 0), or // have a condition (child 1). - not (e instanceof ForStmt and i = [1, 2]) + not (e instanceof ForStmt and i = [1, 2]) and + // Kotlin-extracted annotations can have missing children where a default + // value should be, because kotlinc doesn't load annotation defaults and we + // want to leave a space for another extractor to fill in the default if it + // is able. + not e instanceof Annotation } from Element e, int i, string problem diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected new file mode 100644 index 00000000000..751777f3748 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected @@ -0,0 +1,301 @@ +User.java: +# 0| [CompilationUnit] User +# 1| 1: [Class] User +# 3| 2: [Method] user +# 3| 3: [TypeAccess] void +#-----| 4: (Parameters) +# 3| 0: [Parameter] a1 +# 3| 0: [TypeAccess] Ann1 +# 3| 1: [Parameter] a2 +# 3| 0: [TypeAccess] Ann2 +# 3| 5: [BlockStmt] { ... } +# 4| 0: [ExprStmt] ; +# 4| 0: [MethodAccess] x(...) +# 4| -1: [VarAccess] a1 +# 4| 1: [ExprStmt] ; +# 4| 0: [MethodAccess] z(...) +# 4| -1: [VarAccess] a2 +# 4| 2: [ExprStmt] ; +# 4| 0: [ClassInstanceExpr] new Annotated(...) +# 4| -3: [TypeAccess] Annotated +# 4| 3: [ExprStmt] ; +# 4| 0: [ClassInstanceExpr] new HasJavaDeprecatedAnnotationUsedByJava(...) +# 4| -3: [TypeAccess] HasJavaDeprecatedAnnotationUsedByJava +# 4| 4: [ExprStmt] ; +# 4| 0: [ClassInstanceExpr] new HasKotlinDeprecatedAnnotationUsedByJava(...) +# 4| -3: [TypeAccess] HasKotlinDeprecatedAnnotationUsedByJava +ktUser.kt: +# 0| [CompilationUnit] ktUser +# 1| 1: [Class] KtUser +# 1| 1: [Constructor] KtUser +# 1| 5: [BlockStmt] { ... } +# 1| 0: [SuperConstructorInvocationStmt] super(...) +# 1| 1: [BlockStmt] { ... } +# 3| 2: [Method] user +# 3| 3: [TypeAccess] Unit +# 3| 5: [BlockStmt] { ... } +# 4| 0: [LocalVariableDeclStmt] var ...; +# 4| 1: [LocalVariableDeclExpr] a +# 4| 0: [ClassInstanceExpr] new AnnotatedUsedByKotlin(...) +# 4| -3: [TypeAccess] AnnotatedUsedByKotlin +# 5| 1: [LocalVariableDeclStmt] var ...; +# 5| 1: [LocalVariableDeclExpr] b +# 5| 0: [ClassInstanceExpr] new HasJavaDeprecatedAnnotationUsedByKotlin(...) +# 5| -3: [TypeAccess] HasJavaDeprecatedAnnotationUsedByKotlin +# 6| 2: [LocalVariableDeclStmt] var ...; +# 6| 1: [LocalVariableDeclExpr] c +# 6| 0: [ClassInstanceExpr] new HasKotlinDeprecatedAnnotationUsedByKotlin(...) +# 6| -3: [TypeAccess] HasKotlinDeprecatedAnnotationUsedByKotlin +# 8| 3: [ExprStmt] ; +# 8| 0: [ImplicitCoercionToUnitExpr] +# 8| 0: [TypeAccess] Unit +# 8| 1: [MethodAccess] isJavaLetter(...) +# 8| -1: [TypeAccess] Character +# 8| 0: [CharacterLiteral] a +test.kt: +# 0| [CompilationUnit] test +# 4| 1: [Interface] Ann1 +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 4| 1: [Method] x +# 4| 3: [TypeAccess] int +# 4| 2: [Method] y +# 4| 3: [TypeAccess] Ann2 +# 4| 3: [Method] z +# 4| 3: [TypeAccess] DayOfWeek +# 6| 2: [Interface] Ann2 +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 6| 1: [Method] z +# 6| 3: [TypeAccess] String +# 6| 2: [Method] w +# 6| 3: [TypeAccess] Class +# 6| 0: [WildcardTypeAccess] ? ... +# 6| 3: [Method] v +# 6| 3: [TypeAccess] int[] +# 6| 4: [Method] u +# 6| 3: [TypeAccess] Ann3[] +# 6| 0: [TypeAccess] Ann3 +# 6| 5: [Method] t +# 6| 3: [TypeAccess] Class[] +# 6| 0: [TypeAccess] Class +# 6| 0: [WildcardTypeAccess] ? ... +# 8| 3: [Interface] Ann3 +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 8| 1: [Method] a +# 8| 3: [TypeAccess] int +# 10| 4: [GenericType,Interface,ParameterizedType] GenericAnnotation +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +#-----| -2: (Generic Parameters) +# 10| 0: [TypeVariable] T +# 10| 1: [Method] x +# 10| 3: [TypeAccess] Class +# 10| 0: [TypeAccess] T +# 10| 2: [Method] y +# 10| 3: [TypeAccess] Class[] +# 10| 0: [TypeAccess] Class +# 10| 0: [TypeAccess] T +# 12| 6: [Interface] VarargAnnotation +#-----| -3: (Annotations) +# 0| 1: [Annotation] Repeatable +# 0| 1: [TypeLiteral] Container.class +# 0| 0: [TypeAccess] Container +# 0| 2: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 12| 3: [Annotation] Repeatable +# 0| 1: [Interface] Container +#-----| -3: (Annotations) +# 0| 1: [Annotation] RepeatableContainer +# 0| 2: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 0| 1: [Method] value +# 0| 3: [TypeAccess] VarargAnnotation[] +# 0| 0: [TypeAccess] VarargAnnotation +# 13| 2: [Method] x +# 13| 3: [TypeAccess] int[] +# 15| 7: [Interface] AnnWithDefaults +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 15| 1: [Method] x +# 15| 3: [TypeAccess] int +# 15| 2: [Method] y +# 15| 3: [TypeAccess] String +# 15| 3: [Method] z +# 15| 3: [TypeAccess] DayOfWeek +# 15| 4: [Method] w +# 15| 3: [TypeAccess] Ann3[] +# 15| 0: [TypeAccess] Ann3 +# 17| 8: [Class] Annotated +#-----| -3: (Annotations) +# 0| 1: [Annotation] Container +# 0| 1: [ArrayInit] {...} +# 19| 1: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 20| 2: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 21| 3: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 22| 4: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 23| 5: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 17| 2: [Annotation] Ann1 +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [Annotation] Ann2 +# 0| 1: [StringLiteral] "Hello" +# 0| 2: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 3: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 0| 4: [ArrayInit] {...} +# 0| 1: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 2 +# 0| 5: [ArrayInit] {...} +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [TypeLiteral] int.class +# 0| 0: [TypeAccess] int +# 0| 3: [VarAccess] DayOfWeek.MONDAY +# 0| -1: [TypeAccess] DayOfWeek +# 18| 3: [Annotation] GenericAnnotation +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [ArrayInit] {...} +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 24| 4: [Annotation] AnnWithDefaults +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [StringLiteral] "hello" +# 0| 3: [VarAccess] DayOfWeek.TUESDAY +# 0| -1: [TypeAccess] DayOfWeek +# 0| 4: [ArrayInit] {...} +# 0| 1: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 1 +# 25| 1: [Constructor] Annotated +# 17| 5: [BlockStmt] { ... } +# 17| 0: [SuperConstructorInvocationStmt] super(...) +# 25| 1: [BlockStmt] { ... } +# 27| 9: [Class] AnnotatedUsedByKotlin +#-----| -3: (Annotations) +# 0| 1: [Annotation] Container +# 0| 1: [ArrayInit] {...} +# 29| 1: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 30| 2: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 31| 3: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 32| 4: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 33| 5: [Annotation] VarargAnnotation +# 0| 1: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 27| 2: [Annotation] Ann1 +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [Annotation] Ann2 +# 0| 1: [StringLiteral] "Hello" +# 0| 2: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 3: [ArrayInit] {...} +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [IntegerLiteral] 2 +# 0| 3: [IntegerLiteral] 3 +# 0| 4: [ArrayInit] {...} +# 0| 1: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 2 +# 0| 5: [ArrayInit] {...} +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [TypeLiteral] int.class +# 0| 0: [TypeAccess] int +# 0| 3: [VarAccess] DayOfWeek.MONDAY +# 0| -1: [TypeAccess] DayOfWeek +# 28| 3: [Annotation] GenericAnnotation +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [ArrayInit] {...} +# 0| 1: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 0| 2: [TypeLiteral] String.class +# 0| 0: [TypeAccess] String +# 34| 4: [Annotation] AnnWithDefaults +# 0| 1: [IntegerLiteral] 1 +# 0| 2: [StringLiteral] "hello" +# 0| 3: [VarAccess] DayOfWeek.TUESDAY +# 0| -1: [TypeAccess] DayOfWeek +# 0| 4: [ArrayInit] {...} +# 0| 1: [Annotation] Ann3 +# 0| 1: [IntegerLiteral] 1 +# 35| 1: [Constructor] AnnotatedUsedByKotlin +# 27| 5: [BlockStmt] { ... } +# 27| 0: [SuperConstructorInvocationStmt] super(...) +# 35| 1: [BlockStmt] { ... } +# 37| 10: [Class] HasJavaDeprecatedAnnotationUsedByJava +#-----| -3: (Annotations) +# 37| 1: [Annotation] Deprecated +# 38| 1: [Constructor] HasJavaDeprecatedAnnotationUsedByJava +# 37| 5: [BlockStmt] { ... } +# 37| 0: [SuperConstructorInvocationStmt] super(...) +# 38| 1: [BlockStmt] { ... } +# 40| 11: [Class] HasKotlinDeprecatedAnnotationUsedByJava +#-----| -3: (Annotations) +# 40| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "Kotlin deprecation message 1" +# 41| 1: [Constructor] HasKotlinDeprecatedAnnotationUsedByJava +# 40| 5: [BlockStmt] { ... } +# 40| 0: [SuperConstructorInvocationStmt] super(...) +# 41| 1: [BlockStmt] { ... } +# 43| 12: [Class] HasJavaDeprecatedAnnotationUsedByKotlin +#-----| -3: (Annotations) +# 43| 1: [Annotation] Deprecated +# 44| 1: [Constructor] HasJavaDeprecatedAnnotationUsedByKotlin +# 43| 5: [BlockStmt] { ... } +# 43| 0: [SuperConstructorInvocationStmt] super(...) +# 44| 1: [BlockStmt] { ... } +# 46| 13: [Class] HasKotlinDeprecatedAnnotationUsedByKotlin +#-----| -3: (Annotations) +# 46| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "Kotlin deprecation message 2" +# 47| 1: [Constructor] HasKotlinDeprecatedAnnotationUsedByKotlin +# 46| 5: [BlockStmt] { ... } +# 46| 0: [SuperConstructorInvocationStmt] super(...) +# 47| 1: [BlockStmt] { ... } diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.qlref b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.qlref new file mode 100644 index 00000000000..c7fd5faf239 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/java/PrintAst.ql \ No newline at end of file diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/User.java b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/User.java new file mode 100644 index 00000000000..004e770ba96 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/User.java @@ -0,0 +1,7 @@ +public class User { + + public static void user(Ann1 a1, Ann2 a2) { + a1.x(); a2.z(); new Annotated(); new HasJavaDeprecatedAnnotationUsedByJava(); new HasKotlinDeprecatedAnnotationUsedByJava(); + } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.expected b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.expected new file mode 100644 index 00000000000..76685549259 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.expected @@ -0,0 +1,5 @@ +| HasJavaDeprecatedAnnotationUsedByJava | java.lang.Deprecated | +| HasJavaDeprecatedAnnotationUsedByKotlin | java.lang.Deprecated | +| HasKotlinDeprecatedAnnotationUsedByJava | kotlin.Deprecated | +| HasKotlinDeprecatedAnnotationUsedByKotlin | kotlin.Deprecated | +| isJavaLetter | java.lang.Deprecated | diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.ql b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.ql new file mode 100644 index 00000000000..d8face48b56 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.ql @@ -0,0 +1,11 @@ +import java + +from Annotatable a, Annotation ann +where + ( + a.(Method).hasQualifiedName("java.lang", "Character", "isJavaLetter") or + a.(ClassOrInterface).fromSource() + ) and + ann = a.getAnAnnotation() and + ann.getType().getName() = "Deprecated" +select a.toString(), a.getAnAnnotation().getType().getQualifiedName() diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt new file mode 100644 index 00000000000..cb593ce11f1 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt @@ -0,0 +1,11 @@ +public class KtUser { + + fun user() { + val a = AnnotatedUsedByKotlin() + val b = HasJavaDeprecatedAnnotationUsedByKotlin() + val c = HasKotlinDeprecatedAnnotationUsedByKotlin() + // Use a Java-defined function carrying a java.lang.Deprecated annotation: + java.lang.Character.isJavaLetter('a') + } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/qlpack.yml new file mode 100644 index 00000000000..74fbac535d7 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/qlpack.yml @@ -0,0 +1,7 @@ +name: integrationtest-annotation-id-consistency +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' +dataExtensions: + ext/*.model.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.ext.yml new file mode 100644 index 00000000000..4d7a2e9a149 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.ext.yml @@ -0,0 +1,5 @@ +extensions: + - addsTo: + pack: integrationtest-annotation-id-consistency + extensible: neutralModel + data: [] diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt new file mode 100644 index 00000000000..44746342ae6 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt @@ -0,0 +1,47 @@ +import kotlin.reflect.KClass +import java.time.DayOfWeek + +annotation class Ann1(val x: Int, val y: Ann2, val z: DayOfWeek) { } + +annotation class Ann2(val z: String, val w: KClass<*>, val v: IntArray, val u: Array, val t: Array>) { } + +annotation class Ann3(val a: Int) { } + +annotation class GenericAnnotation(val x: KClass, val y: Array>) { } + +@Repeatable +annotation class VarargAnnotation(vararg val x: Int) { } + +annotation class AnnWithDefaults(val x: Int = 1, val y: String = "hello", val z: DayOfWeek = DayOfWeek.TUESDAY, val w: Array = [Ann3(1)]) { } + +@Ann1(1, Ann2("Hello", String::class, intArrayOf(1, 2, 3), arrayOf(Ann3(1), Ann3(2)), arrayOf(String::class, Int::class)), DayOfWeek.MONDAY) +@GenericAnnotation(String::class, arrayOf(String::class, String::class)) +@VarargAnnotation +@VarargAnnotation(1) +@VarargAnnotation(1, 2) +@VarargAnnotation(*[1, 2, 3]) +@VarargAnnotation(*intArrayOf(1, 2, 3)) +@AnnWithDefaults +class Annotated { } + +@Ann1(1, Ann2("Hello", String::class, intArrayOf(1, 2, 3), arrayOf(Ann3(1), Ann3(2)), arrayOf(String::class, Int::class)), DayOfWeek.MONDAY) +@GenericAnnotation(String::class, arrayOf(String::class, String::class)) +@VarargAnnotation +@VarargAnnotation(1) +@VarargAnnotation(1, 2) +@VarargAnnotation(*[1, 2, 3]) +@VarargAnnotation(*intArrayOf(1, 2, 3)) +@AnnWithDefaults +class AnnotatedUsedByKotlin { } + +@java.lang.Deprecated +class HasJavaDeprecatedAnnotationUsedByJava + +@kotlin.Deprecated("Kotlin deprecation message 1") +class HasKotlinDeprecatedAnnotationUsedByJava + +@java.lang.Deprecated +class HasJavaDeprecatedAnnotationUsedByKotlin + +@kotlin.Deprecated("Kotlin deprecation message 2") +class HasKotlinDeprecatedAnnotationUsedByKotlin diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.py b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.py new file mode 100644 index 00000000000..49584531332 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.py @@ -0,0 +1,5 @@ +from create_database_utils import * + +os.mkdir('out') +os.mkdir('out2') +run_codeql_database_create(["kotlinc test.kt -d out", "javac User.java -cp out -d out2", "kotlinc ktUser.kt -cp out -d out2"], lang="java") diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml new file mode 100644 index 00000000000..f1e981e8791 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml @@ -0,0 +1,7 @@ +name: integrationtest-default-parameter-mad-flow +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' +dataExtensions: + ext/*.model.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ext.yml new file mode 100644 index 00000000000..3553b9fe577 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ext.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: summaryModel + data: + - ["", "ConstructorWithDefaults", True, "ConstructorWithDefaults", "(int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "LibKt", True, "topLevelWithDefaults", "(int,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["", "LibKt", True, "extensionWithDefaults", "(String,int,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "memberWithDefaults", "(int,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "extensionMemberWithDefaults", "(String,int,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "multiParameterTest", "(int,int,int,int)", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["", "LibClass", True, "multiParameterExtensionTest", "(int,int,int,int)", "", "Argument[0, 1]", "ReturnValue", "value", "manual"] + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: sourceModel + data: + - ["", "LibKt", True, "topLevelArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "extensionArgSource", "(String,SomeToken,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] + - ["", "SourceClass", True, "memberArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - addsTo: + pack: integrationtest-default-parameter-mad-flow + extensible: sinkModel + data: + - ["", "SinkClass", True, "SinkClass", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "topLevelSink", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "LibKt", True, "extensionSink", "(String,int,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] + - ["", "SinkClass", True, "memberSink", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"] + - ["", "SinkClass", True, "extensionMemberSink", "(String,int,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"] diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql index b9b4423d94a..702b137fad7 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql @@ -3,45 +3,6 @@ import semmle.code.java.dataflow.TaintTracking import TestUtilities.InlineExpectationsTest private import semmle.code.java.dataflow.ExternalFlow -private class Models extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - ";ConstructorWithDefaults;true;ConstructorWithDefaults;(int,int);;Argument[0];Argument[-1];taint;manual", - ";LibKt;true;topLevelWithDefaults;(int,int);;Argument[0];ReturnValue;value;manual", - ";LibKt;true;extensionWithDefaults;(String,int,int);;Argument[1];ReturnValue;value;manual", - ";LibClass;true;memberWithDefaults;(int,int);;Argument[0];ReturnValue;value;manual", - ";LibClass;true;extensionMemberWithDefaults;(String,int,int);;Argument[1];ReturnValue;value;manual", - ";LibClass;true;multiParameterTest;(int,int,int,int);;Argument[0..1];ReturnValue;value;manual", - ";LibClass;true;multiParameterExtensionTest;(int,int,int,int);;Argument[0, 1];ReturnValue;value;manual", - ] - } -} - -private class SourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - ";LibKt;true;topLevelArgSource;(SomeToken,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;extensionArgSource;(String,SomeToken,int);;Argument[1];kotlinMadFlowTest;manual", - ";SourceClass;true;memberArgSource;(SomeToken,int);;Argument[0];kotlinMadFlowTest;manual" - ] - } -} - -private class SinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - ";SinkClass;true;SinkClass;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;topLevelSink;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";LibKt;true;extensionSink;(String,int,int);;Argument[1];kotlinMadFlowTest;manual", - ";SinkClass;true;memberSink;(int,int);;Argument[0];kotlinMadFlowTest;manual", - ";SinkClass;true;extensionMemberSink;(String,int,int);;Argument[1];kotlinMadFlowTest;manual" - ] - } -} - class Config extends TaintTracking::Configuration { Config() { this = "Config" } diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected b/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected index 04702df7916..e78d827c621 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected @@ -2,7 +2,7 @@ exprs | Test.java:5:19:5:25 | Integer | Integer | | Test.java:5:38:5:44 | Integer | Integer | | Test.java:5:58:5:58 | p | Integer | -| user.kt:2:3:2:16 | x | int | +| user.kt:2:7:2:7 | x | int | | user.kt:2:11:2:11 | t | Test | | user.kt:2:11:2:16 | f(...) | Integer | | user.kt:2:13:2:16 | | int | diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected index ae23298c033..a81cadccd10 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected @@ -1,7 +1,17 @@ app/src/main/kotlin/testProject/App.kt: # 0| [CompilationUnit] App # 7| 1: [Class] Project +#-----| -3: (Annotations) +# 7| 1: [Annotation] Serializable # 0| 1: [Constructor] Project +#-----| 1: (Annotations) +# 0| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "This synthesized declaration should not be used directly" +# 0| 2: [Annotation] ReplaceWith +# 0| 1: [StringLiteral] "" +# 0| 2: [ArrayInit] {...} +# 0| 3: [VarAccess] DeprecationLevel.HIDDEN +# 0| -1: [TypeAccess] DeprecationLevel #-----| 4: (Parameters) # 0| 0: [Parameter] seen1 # 0| 0: [TypeAccess] int @@ -41,6 +51,8 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [TypeAccess] Project # 7| 1: [VarAccess] language # 0| 2: [Method] component1 +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... @@ -53,9 +65,13 @@ app/src/main/kotlin/testProject/App.kt: # 0| 0: [VarAccess] this.language # 0| -1: [ThisAccess] this # 0| 4: [Method] copy +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 8| 0: [TypeAccess] String # 8| 1: [Parameter] language # 8| 0: [TypeAccess] int @@ -176,27 +192,37 @@ app/src/main/kotlin/testProject/App.kt: # 0| 2: [ReturnStmt] return ... # 0| 0: [VarAccess] result # 0| 8: [Method] toString +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] Project( -# 0| 1: [StringLiteral] name= +# 0| 0: [StringLiteral] "Project(" +# 0| 1: [StringLiteral] "name=" # 0| 2: [VarAccess] this.name # 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] language= +# 0| 3: [StringLiteral] ", " +# 0| 4: [StringLiteral] "language=" # 0| 5: [VarAccess] this.language # 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) +# 0| 6: [StringLiteral] ")" # 0| 9: [Method] write$Self +#-----| 1: (Annotations) +# 0| 1: [Annotation] JvmStatic # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] self +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Project # 0| 1: [Parameter] output +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] CompositeEncoder # 0| 2: [Parameter] serialDesc +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] SerialDescriptor # 7| 5: [BlockStmt] { ... } # 7| 0: [ExprStmt] ; @@ -214,9 +240,19 @@ app/src/main/kotlin/testProject/App.kt: # 7| 2: [MethodAccess] getLanguage(...) # 7| -1: [VarAccess] self # 7| 10: [Class] $serializer +#-----| -3: (Annotations) +# 0| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "This synthesized declaration should not be used directly" +# 0| 2: [Annotation] ReplaceWith +# 0| 1: [StringLiteral] "" +# 0| 2: [ArrayInit] {...} +# 0| 3: [VarAccess] DeprecationLevel.HIDDEN +# 0| -1: [TypeAccess] DeprecationLevel # 0| 1: [FieldDeclaration] SerialDescriptor descriptor; # 0| -1: [TypeAccess] SerialDescriptor # 0| 2: [Method] childSerializers +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] KSerializer[] # 0| 0: [TypeAccess] KSerializer # 0| 0: [WildcardTypeAccess] ? ... @@ -227,9 +263,13 @@ app/src/main/kotlin/testProject/App.kt: # 7| -1: [TypeAccess] KSerializer # 7| 0: [IntegerLiteral] 2 # 0| 3: [Method] deserialize +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 0| 0: [Parameter] decoder +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Decoder # 7| 5: [BlockStmt] { ... } # 7| 0: [LocalVariableDeclStmt] var ...; @@ -365,6 +405,8 @@ app/src/main/kotlin/testProject/App.kt: # 7| 2: [VarAccess] tmp5_local1 # 7| 3: [NullLiteral] null # 0| 4: [Method] getDescriptor +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] SerialDescriptor # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... @@ -374,8 +416,12 @@ app/src/main/kotlin/testProject/App.kt: # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] encoder +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Encoder # 0| 1: [Parameter] value +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Project # 7| 5: [BlockStmt] { ... } # 7| 0: [LocalVariableDeclStmt] var ...; @@ -405,19 +451,19 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [LocalVariableDeclExpr] tmp0_serialDesc # 7| 0: [ClassInstanceExpr] new PluginGeneratedSerialDescriptor(...) # 7| -3: [TypeAccess] PluginGeneratedSerialDescriptor -# 7| 0: [StringLiteral] testProject.Project +# 7| 0: [StringLiteral] "testProject.Project" # 7| 1: [ThisAccess] $serializer.this # 7| 0: [TypeAccess] $serializer # 7| 2: [IntegerLiteral] 2 # 7| 1: [ExprStmt] ; # 7| 0: [MethodAccess] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc -# 7| 0: [StringLiteral] name +# 7| 0: [StringLiteral] "name" # 7| 1: [BooleanLiteral] false # 7| 2: [ExprStmt] ; # 7| 0: [MethodAccess] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc -# 7| 0: [StringLiteral] language +# 7| 0: [StringLiteral] "language" # 7| 1: [BooleanLiteral] false # 7| 3: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... @@ -436,6 +482,8 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [TypeAccess] GeneratedSerializer # 7| 11: [Class] Companion # 0| 1: [Method] serializer +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] KSerializer # 0| 0: [TypeAccess] Project # 7| 5: [BlockStmt] { ... } @@ -448,6 +496,8 @@ app/src/main/kotlin/testProject/App.kt: # 8| 12: [Constructor] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 8| 0: [TypeAccess] String # 8| 1: [Parameter] language # 8| 0: [TypeAccess] int @@ -464,6 +514,8 @@ app/src/main/kotlin/testProject/App.kt: # 8| -1: [TypeAccess] String # 8| 0: [VarAccess] name # 8| 14: [Method] getName +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 8| 3: [TypeAccess] String # 8| 5: [BlockStmt] { ... } # 8| 0: [ReturnStmt] return ... @@ -480,9 +532,21 @@ app/src/main/kotlin/testProject/App.kt: # 8| 0: [VarAccess] language # 10| 2: [Interface] Base # 11| 1: [Method] getId +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 11| 3: [TypeAccess] String # 14| 3: [Class] X +#-----| -3: (Annotations) +# 14| 1: [Annotation] Serializable # 0| 1: [Constructor] X +#-----| 1: (Annotations) +# 0| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "This synthesized declaration should not be used directly" +# 0| 2: [Annotation] ReplaceWith +# 0| 1: [StringLiteral] "" +# 0| 2: [ArrayInit] {...} +# 0| 3: [VarAccess] DeprecationLevel.HIDDEN +# 0| -1: [TypeAccess] DeprecationLevel #-----| 4: (Parameters) # 0| 0: [Parameter] seen1 # 0| 0: [TypeAccess] int @@ -520,7 +584,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [VarAccess] X.this.id # 14| -1: [ThisAccess] X.this # 14| 0: [TypeAccess] X -# 16| 1: [StringLiteral] X +# 16| 1: [StringLiteral] "X" # 14| 1: [WhenBranch] ... -> ... # 14| 0: [BooleanLiteral] true # 14| 1: [ExprStmt] ; @@ -530,13 +594,21 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [TypeAccess] X # 14| 1: [VarAccess] id # 0| 2: [Method] write$Self +#-----| 1: (Annotations) +# 0| 1: [Annotation] JvmStatic # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] self +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] X # 0| 1: [Parameter] output +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] CompositeEncoder # 0| 2: [Parameter] serialDesc +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] SerialDescriptor # 14| 5: [BlockStmt] { ... } # 14| 0: [ExprStmt] ; @@ -556,7 +628,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [ValueNEExpr] ... (value not-equals) ... # 14| 0: [MethodAccess] getId(...) # 14| -1: [VarAccess] self -# 16| 1: [StringLiteral] X +# 16| 1: [StringLiteral] "X" # 14| 1: [ExprStmt] ; # 14| 0: [MethodAccess] encodeStringElement(...) # 14| -1: [VarAccess] output @@ -565,9 +637,19 @@ app/src/main/kotlin/testProject/App.kt: # 14| 2: [MethodAccess] getId(...) # 14| -1: [VarAccess] self # 14| 3: [Class] $serializer +#-----| -3: (Annotations) +# 0| 1: [Annotation] Deprecated +# 0| 1: [StringLiteral] "This synthesized declaration should not be used directly" +# 0| 2: [Annotation] ReplaceWith +# 0| 1: [StringLiteral] "" +# 0| 2: [ArrayInit] {...} +# 0| 3: [VarAccess] DeprecationLevel.HIDDEN +# 0| -1: [TypeAccess] DeprecationLevel # 0| 1: [FieldDeclaration] SerialDescriptor descriptor; # 0| -1: [TypeAccess] SerialDescriptor # 0| 2: [Method] childSerializers +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] KSerializer[] # 0| 0: [TypeAccess] KSerializer # 0| 0: [WildcardTypeAccess] ? ... @@ -578,9 +660,13 @@ app/src/main/kotlin/testProject/App.kt: # 14| -1: [TypeAccess] KSerializer # 14| 0: [IntegerLiteral] 1 # 0| 3: [Method] deserialize +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] X #-----| 4: (Parameters) # 0| 0: [Parameter] decoder +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Decoder # 14| 5: [BlockStmt] { ... } # 14| 0: [LocalVariableDeclStmt] var ...; @@ -680,6 +766,8 @@ app/src/main/kotlin/testProject/App.kt: # 14| 1: [VarAccess] tmp4_local0 # 14| 2: [NullLiteral] null # 0| 4: [Method] getDescriptor +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] SerialDescriptor # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... @@ -689,8 +777,12 @@ app/src/main/kotlin/testProject/App.kt: # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] encoder +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] Encoder # 0| 1: [Parameter] value +#-----| -1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 0: [TypeAccess] X # 14| 5: [BlockStmt] { ... } # 14| 0: [LocalVariableDeclStmt] var ...; @@ -720,14 +812,14 @@ app/src/main/kotlin/testProject/App.kt: # 14| 1: [LocalVariableDeclExpr] tmp0_serialDesc # 14| 0: [ClassInstanceExpr] new PluginGeneratedSerialDescriptor(...) # 14| -3: [TypeAccess] PluginGeneratedSerialDescriptor -# 14| 0: [StringLiteral] testProject.X +# 14| 0: [StringLiteral] "testProject.X" # 14| 1: [ThisAccess] $serializer.this # 14| 0: [TypeAccess] $serializer # 14| 2: [IntegerLiteral] 1 # 14| 1: [ExprStmt] ; # 14| 0: [MethodAccess] addElement(...) # 14| -1: [VarAccess] tmp0_serialDesc -# 14| 0: [StringLiteral] id +# 14| 0: [StringLiteral] "id" # 14| 1: [BooleanLiteral] true # 14| 2: [ExprStmt] ; # 14| 0: [AssignExpr] ...=... @@ -746,6 +838,8 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [TypeAccess] GeneratedSerializer # 14| 4: [Class] Companion # 0| 1: [Method] serializer +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 0| 3: [TypeAccess] KSerializer # 0| 0: [TypeAccess] X # 14| 5: [BlockStmt] { ... } @@ -764,8 +858,10 @@ app/src/main/kotlin/testProject/App.kt: # 16| 0: [VarAccess] id # 16| 6: [FieldDeclaration] String id; # 16| -1: [TypeAccess] String -# 16| 0: [StringLiteral] X +# 16| 0: [StringLiteral] "X" # 16| 7: [Method] getId +#-----| 1: (Annotations) +# 0| 1: [Annotation] NotNull # 16| 3: [TypeAccess] String # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml new file mode 100644 index 00000000000..8b18f2ea94a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-gradle-kotlinx-serialization +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/User.java b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/User.java new file mode 100644 index 00000000000..c3356f588d5 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/User.java @@ -0,0 +1,6 @@ +@AllDefaultsAnnotation +public class User { + + public static void test() { new AllDefaultsConstructor(); new AllDefaultsExplicitNoargConstructor(); } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt index 0996b3f158a..33e6d1d1221 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt +++ b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt @@ -3,3 +3,13 @@ public class Test { @JvmOverloads fun f(x: Int = 0, y: Int) { } } + +public class AllDefaultsConstructor(val x: Int = 1, val y: Int = 2) { } + +public annotation class AllDefaultsAnnotation(val x: Int = 1, val y: Int = 2) { } + +public class AllDefaultsExplicitNoargConstructor(val x: Int = 1, val y: Int = 2) { + + constructor() : this(3, 4) { } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py index b763a28daa9..1416b7ecd67 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py +++ b/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py @@ -1,4 +1,4 @@ from create_database_utils import * os.mkdir('bin') -run_codeql_database_create(["kotlinc test.kt -d bin", "kotlinc user.kt -cp bin"], lang="java") +run_codeql_database_create(["kotlinc test.kt -d bin", "kotlinc user.kt -cp bin", "javac User.java -cp bin"], lang="java") diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml new file mode 100644 index 00000000000..814d1059ed5 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-kotlin-interface-inherited-default +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected b/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected index 5be9218762e..1e32d73cc27 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected @@ -1,3 +1,4 @@ | J.java:1:14:1:14 | J | | build/J.class:0:0:0:0 | J | +| file:///!unknown-binary-location/J.class:0:0:0:0 | J<> | | file:///!unknown-binary-location/J.class:0:0:0:0 | J | diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml new file mode 100644 index 00000000000..ecc3ee3e4ff --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/qlpack.yml @@ -0,0 +1,5 @@ +name: integrationtest-kotlin-java-static-fields +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected index 3581a178422..9f16308bdfc 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected @@ -1,26 +1,26 @@ edges | hasFields.kt:5:5:5:34 | constField : String | ReadsFields.java:5:10:5:29 | HasFields.constField | -| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:5:5:34 | constField : String | +| hasFields.kt:5:28:5:34 | "taint" : String | hasFields.kt:5:5:5:34 | constField : String | | hasFields.kt:7:5:7:38 | lateinitField : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | | hasFields.kt:7:14:7:38 | : String | hasFields.kt:7:5:7:38 | lateinitField : String | | hasFields.kt:7:14:7:38 | : String | hasFields.kt:7:14:7:38 | : String | | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | -| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | -| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:7:14:7:38 | : String | +| hasFields.kt:9:44:9:50 | "taint" : String | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | +| hasFields.kt:14:22:14:26 | "taint" : String | hasFields.kt:7:14:7:38 | : String | nodes | ReadsFields.java:5:10:5:29 | HasFields.constField | semmle.label | HasFields.constField | | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | semmle.label | HasFields.lateinitField | | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | semmle.label | HasFields.jvmFieldAnnotatedField | | hasFields.kt:5:5:5:34 | constField : String | semmle.label | constField : String | -| hasFields.kt:5:28:5:34 | taint : String | semmle.label | taint : String | +| hasFields.kt:5:28:5:34 | "taint" : String | semmle.label | "taint" : String | | hasFields.kt:7:5:7:38 | lateinitField : String | semmle.label | lateinitField : String | | hasFields.kt:7:14:7:38 | : String | semmle.label | : String | | hasFields.kt:7:14:7:38 | : String | semmle.label | : String | | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | semmle.label | jvmFieldAnnotatedField : String | -| hasFields.kt:9:44:9:50 | taint : String | semmle.label | taint : String | -| hasFields.kt:14:22:14:26 | taint : String | semmle.label | taint : String | +| hasFields.kt:9:44:9:50 | "taint" : String | semmle.label | "taint" : String | +| hasFields.kt:14:22:14:26 | "taint" : String | semmle.label | "taint" : String | subpaths #select -| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:28:5:34 | taint : String | ReadsFields.java:5:10:5:29 | HasFields.constField | flow path | -| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:44:9:50 | taint : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | flow path | -| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:14:22:14:26 | taint : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | flow path | +| hasFields.kt:5:28:5:34 | "taint" : String | hasFields.kt:5:28:5:34 | "taint" : String | ReadsFields.java:5:10:5:29 | HasFields.constField | flow path | +| hasFields.kt:9:44:9:50 | "taint" : String | hasFields.kt:9:44:9:50 | "taint" : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | flow path | +| hasFields.kt:14:22:14:26 | "taint" : String | hasFields.kt:14:22:14:26 | "taint" : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | flow path | diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected index 27db355f838..0441e5afe70 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected @@ -76,7 +76,7 @@ callArgs | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | -2 | | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:34:10:65 | InnerGeneric | -3 | | KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:47:10:49 | a | 0 | -| KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:53:10:63 | hello world | 1 | +| KotlinUser.kt:10:34:10:65 | new InnerGeneric(...) | KotlinUser.kt:10:53:10:63 | "hello world" | 1 | | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | KotlinUser.kt:11:13:11:31 | OuterGeneric | -3 | | KotlinUser.kt:11:33:11:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:11:33:11:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:11:33:11:49 | InnerNotGeneric<> | -3 | @@ -88,10 +88,10 @@ callArgs | KotlinUser.kt:13:31:13:52 | new InnerGeneric(...) | KotlinUser.kt:13:31:13:52 | InnerGeneric | -3 | | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:26:14:63 | InnerStaticGeneric | -3 | | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:45:14:47 | a | 0 | -| KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:51:14:61 | hello world | 1 | +| KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | KotlinUser.kt:14:51:14:61 | "hello world" | 1 | | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:13:15:39 | OuterManyParams | -3 | | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:29:15:29 | 1 | 0 | -| KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:33:15:37 | hello | 1 | +| KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | KotlinUser.kt:15:33:15:37 | "hello" | 1 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | -2 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:41:15:67 | MiddleManyParams | -3 | | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | KotlinUser.kt:15:58:15:61 | 1.0 | 0 | @@ -103,23 +103,23 @@ callArgs | KotlinUser.kt:15:89:15:99 | shortValue(...) | KotlinUser.kt:15:89:15:89 | 1 | -1 | | KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:19:17:19 | a | -1 | | KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:34:17:34 | 0 | 0 | -| KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:38:17:42 | hello | 1 | +| KotlinUser.kt:17:19:17:44 | returnsecond(...) | KotlinUser.kt:17:38:17:42 | "hello" | 1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:20:18:20 | a | -1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:20:18:50 | Character | -2 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:35:18:35 | 0 | 0 | -| KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:39:18:43 | hello | 1 | +| KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:39:18:43 | "hello" | 1 | | KotlinUser.kt:18:20:18:50 | returnsecond(...) | KotlinUser.kt:18:47:18:49 | a | 2 | | KotlinUser.kt:19:19:19:31 | identity(...) | KotlinUser.kt:19:19:19:19 | b | -1 | | KotlinUser.kt:19:19:19:31 | identity(...) | KotlinUser.kt:19:30:19:30 | 5 | 0 | | KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:20:20:21 | b2 | -1 | -| KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:33:20:37 | hello | 0 | +| KotlinUser.kt:20:20:20:39 | identity(...) | KotlinUser.kt:20:33:20:37 | "hello" | 0 | | KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:19:21:19 | c | -1 | -| KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:31:21:35 | world | 0 | +| KotlinUser.kt:21:19:21:37 | identity(...) | KotlinUser.kt:21:31:21:35 | "world" | 0 | | KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:19:22:19 | d | -1 | -| KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:31:22:37 | goodbye | 0 | +| KotlinUser.kt:22:19:22:39 | identity(...) | KotlinUser.kt:22:31:22:37 | "goodbye" | 0 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:19:23:19 | e | -1 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:33:23:33 | 1 | 0 | -| KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:37:23:41 | hello | 1 | +| KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:37:23:41 | "hello" | 1 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:45:23:48 | 1.0 | 2 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:51:23:53 | 1.0 | 3 | | KotlinUser.kt:23:19:23:71 | returnSixth(...) | KotlinUser.kt:23:56:23:57 | 1 | 4 | @@ -319,28 +319,28 @@ javaKotlinConstructorAgreement | JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | javaKotlinLocalTypeAgreement -| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:10:5:10:98 | InnerNotGeneric<> b | KotlinUser.kt:11:5:11:49 | InnerNotGeneric<> b | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:13:5:13:112 | InnerStaticGeneric d | KotlinUser.kt:14:5:14:63 | InnerStaticGeneric d | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | -| JavaUser.java:14:5:14:249 | InnerManyParams e | KotlinUser.kt:15:5:15:100 | InnerManyParams e | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | -| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | -| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | -| JavaUser.java:27:5:27:72 | TypeParamVisibility tpv | KotlinUser.kt:28:5:28:43 | TypeParamVisibility tpv | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | -| JavaUser.java:28:5:28:111 | VisibleBecauseInner visibleBecauseInner | KotlinUser.kt:29:5:29:58 | VisibleBecauseInner visibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | -| JavaUser.java:29:5:29:172 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | KotlinUser.kt:30:5:30:74 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | -| JavaUser.java:30:5:30:115 | NotVisibleBecauseStatic notVisibleBecauseStatic | KotlinUser.kt:31:5:31:66 | NotVisibleBecauseStatic notVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | -| JavaUser.java:31:5:31:180 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | KotlinUser.kt:32:5:32:82 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | +| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:8:5:8:124 | InnerGeneric a2 | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:9:9:9:9 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:10:9:10:10 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:10:5:10:98 | InnerNotGeneric<> b | KotlinUser.kt:11:9:11:9 | InnerNotGeneric<> b | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:12:9:12:10 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:25:9:25:23 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:13:9:13:9 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:26:9:26:24 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:13:5:13:112 | InnerStaticGeneric d | KotlinUser.kt:14:9:14:9 | InnerStaticGeneric d | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | +| JavaUser.java:14:5:14:249 | InnerManyParams e | KotlinUser.kt:15:9:15:9 | InnerManyParams e | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:12:9:12:10 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:25:9:25:23 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:13:9:13:9 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:26:9:26:24 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:27:5:27:72 | TypeParamVisibility tpv | KotlinUser.kt:28:9:28:11 | TypeParamVisibility tpv | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| JavaUser.java:28:5:28:111 | VisibleBecauseInner visibleBecauseInner | KotlinUser.kt:29:9:29:27 | VisibleBecauseInner visibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | +| JavaUser.java:29:5:29:172 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | KotlinUser.kt:30:9:30:35 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | +| JavaUser.java:30:5:30:115 | NotVisibleBecauseStatic notVisibleBecauseStatic | KotlinUser.kt:31:9:31:31 | NotVisibleBecauseStatic notVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | +| JavaUser.java:31:5:31:180 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | KotlinUser.kt:32:9:32:39 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | #select | JavaUser.java:7:52:7:110 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | JavaUser.java:7:99:7:104 | String | | JavaUser.java:7:53:7:79 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | JavaUser.java:7:70:7:76 | Integer | diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedInterface.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedInterface.java new file mode 100644 index 00000000000..db327383a95 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedInterface.java @@ -0,0 +1,10 @@ +import org.jetbrains.annotations.*; +import zpkg.A; + +public interface AnnotatedInterface { + + public @A @NotNull String notNullAnnotated(@A @NotNull String param); + + public @A @Nullable String nullableAnnotated(@A @Nullable String param); + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedMethods.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedMethods.java new file mode 100644 index 00000000000..16671f5468f --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedMethods.java @@ -0,0 +1,10 @@ +import org.jetbrains.annotations.*; +import zpkg.A; + +public class AnnotatedMethods implements AnnotatedInterface { + + public @A @NotNull String notNullAnnotated(@A @NotNull String param) { return param; } + + public @A @Nullable String nullableAnnotated(@A @Nullable String param) { return param; } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/JavaUser.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/JavaUser.java new file mode 100644 index 00000000000..6031901c3a3 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/JavaUser.java @@ -0,0 +1,8 @@ +public class JavaUser { + + public static void test(KotlinAnnotatedMethods km, KotlinDelegate kd) { + km.f(null); + kd.notNullAnnotated("Hello world"); + } + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/ktUser.kt b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/ktUser.kt new file mode 100644 index 00000000000..06c1d580503 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/ktUser.kt @@ -0,0 +1,9 @@ +import zpkg.A + +class KotlinAnnotatedMethods { + + @A fun f(@A m: AnnotatedMethods): String = m.notNullAnnotated("hello") + m.nullableAnnotated("world")!! + +} + +class KotlinDelegate(c: AnnotatedMethods) : AnnotatedInterface by c { } diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/NotNull.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/NotNull.java new file mode 100644 index 00000000000..60fc85ea9b8 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/NotNull.java @@ -0,0 +1,6 @@ +package org.jetbrains.annotations; + +public @interface NotNull { + String value() default ""; + Class exception() default Exception.class; +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/Nullable.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/Nullable.java new file mode 100644 index 00000000000..6cf82f2db31 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/Nullable.java @@ -0,0 +1,5 @@ +package org.jetbrains.annotations; + +public @interface Nullable { + String value() default ""; +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.expected b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.expected new file mode 100644 index 00000000000..89eb06d26c3 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.expected @@ -0,0 +1,28 @@ +| AnnotatedInterface.java:6:29:6:44 | notNullAnnotated | parameter | AnnotatedInterface.java:6:46:6:47 | A | +| AnnotatedInterface.java:6:29:6:44 | notNullAnnotated | parameter | AnnotatedInterface.java:6:49:6:56 | NotNull | +| AnnotatedInterface.java:6:29:6:44 | notNullAnnotated | return value | AnnotatedInterface.java:6:10:6:11 | A | +| AnnotatedInterface.java:6:29:6:44 | notNullAnnotated | return value | AnnotatedInterface.java:6:13:6:20 | NotNull | +| AnnotatedInterface.java:8:30:8:46 | nullableAnnotated | parameter | AnnotatedInterface.java:8:48:8:49 | A | +| AnnotatedInterface.java:8:30:8:46 | nullableAnnotated | parameter | AnnotatedInterface.java:8:51:8:59 | Nullable | +| AnnotatedInterface.java:8:30:8:46 | nullableAnnotated | return value | AnnotatedInterface.java:8:10:8:11 | A | +| AnnotatedInterface.java:8:30:8:46 | nullableAnnotated | return value | AnnotatedInterface.java:8:13:8:21 | Nullable | +| AnnotatedMethods.java:6:29:6:44 | notNullAnnotated | parameter | AnnotatedMethods.java:6:46:6:47 | A | +| AnnotatedMethods.java:6:29:6:44 | notNullAnnotated | parameter | AnnotatedMethods.java:6:49:6:56 | NotNull | +| AnnotatedMethods.java:6:29:6:44 | notNullAnnotated | return value | AnnotatedMethods.java:6:10:6:11 | A | +| AnnotatedMethods.java:6:29:6:44 | notNullAnnotated | return value | AnnotatedMethods.java:6:13:6:20 | NotNull | +| AnnotatedMethods.java:8:30:8:46 | nullableAnnotated | parameter | AnnotatedMethods.java:8:48:8:49 | A | +| AnnotatedMethods.java:8:30:8:46 | nullableAnnotated | parameter | AnnotatedMethods.java:8:51:8:59 | Nullable | +| AnnotatedMethods.java:8:30:8:46 | nullableAnnotated | return value | AnnotatedMethods.java:8:10:8:11 | A | +| AnnotatedMethods.java:8:30:8:46 | nullableAnnotated | return value | AnnotatedMethods.java:8:13:8:21 | Nullable | +| ktUser.kt:0:0:0:0 | notNullAnnotated | parameter | ktUser.kt:0:0:0:0 | A | +| ktUser.kt:0:0:0:0 | notNullAnnotated | parameter | ktUser.kt:0:0:0:0 | NotNull | +| ktUser.kt:0:0:0:0 | notNullAnnotated | return value | ktUser.kt:0:0:0:0 | A | +| ktUser.kt:0:0:0:0 | notNullAnnotated | return value | ktUser.kt:0:0:0:0 | NotNull | +| ktUser.kt:0:0:0:0 | nullableAnnotated | parameter | ktUser.kt:0:0:0:0 | A | +| ktUser.kt:0:0:0:0 | nullableAnnotated | parameter | ktUser.kt:0:0:0:0 | Nullable | +| ktUser.kt:0:0:0:0 | nullableAnnotated | return value | ktUser.kt:0:0:0:0 | A | +| ktUser.kt:0:0:0:0 | nullableAnnotated | return value | ktUser.kt:0:0:0:0 | Nullable | +| ktUser.kt:5:6:5:105 | f | parameter | ktUser.kt:0:0:0:0 | NotNull | +| ktUser.kt:5:6:5:105 | f | parameter | ktUser.kt:5:12:5:13 | A | +| ktUser.kt:5:6:5:105 | f | return value | ktUser.kt:0:0:0:0 | NotNull | +| ktUser.kt:5:6:5:105 | f | return value | ktUser.kt:5:3:5:4 | A | diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.py b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.py new file mode 100644 index 00000000000..6a27fa40a40 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.py @@ -0,0 +1,7 @@ +from create_database_utils import * +import os + +os.mkdir('out') +os.mkdir('out2') +os.mkdir('out3') +run_codeql_database_create(["javac AnnotatedInterface.java AnnotatedMethods.java zpkg/A.java org/jetbrains/annotations/NotNull.java org/jetbrains/annotations/Nullable.java -d out", "kotlinc ktUser.kt -cp out -d out2", "javac JavaUser.java -cp out" + os.pathsep + "out2 -d out3"], lang="java") diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.ql b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.ql new file mode 100644 index 00000000000..def0233a5a0 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.ql @@ -0,0 +1,11 @@ +import java + +from Method m, string origin, Annotation a +where + m.fromSource() and + ( + origin = "return value" and a = m.getAnAnnotation() + or + origin = "parameter" and a = m.getAParameter().getAnAnnotation() + ) +select m, origin, a diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/zpkg/A.java b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/zpkg/A.java new file mode 100644 index 00000000000..93a36f72500 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/zpkg/A.java @@ -0,0 +1,3 @@ +package zpkg; + +public @interface A { } diff --git a/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml b/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml index 2d76cd00707..9ead02fc564 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml +++ b/java/ql/integration-tests/all-platforms/kotlin/qlpack.yml @@ -1,4 +1,4 @@ -libraryPathDependencies: - - codeql-java - - codeql/java-tests - - codeql/java-queries +dependencies: + codeql/java-all: '*' + codeql/java-tests: '*' + codeql/java-queries: '*' diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedContainer.java b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedContainer.java new file mode 100644 index 00000000000..13d1135669e --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedContainer.java @@ -0,0 +1,5 @@ +public @interface JavaDefinedContainer { + + public JavaDefinedRepeatable[] value(); + +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedRepeatable.java b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedRepeatable.java new file mode 100644 index 00000000000..5eaaf1e2ab2 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedRepeatable.java @@ -0,0 +1,3 @@ +@java.lang.annotation.Repeatable(JavaDefinedContainer.class) +public @interface JavaDefinedRepeatable { } + diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaUser.java b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaUser.java new file mode 100644 index 00000000000..610c373cb0f --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaUser.java @@ -0,0 +1,9 @@ +@LocalRepeatable +@LocalRepeatable +@LibRepeatable +@LibRepeatable +@ExplicitContainerRepeatable +@ExplicitContainerRepeatable +@JavaDefinedRepeatable +@JavaDefinedRepeatable +public class JavaUser { } diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/lib.kt b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/lib.kt new file mode 100644 index 00000000000..3133d3d9e70 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/lib.kt @@ -0,0 +1,7 @@ +@Repeatable +public annotation class LibRepeatable { } + +annotation class KtDefinedContainer(val value: Array) { } + +@java.lang.annotation.Repeatable(KtDefinedContainer::class) +annotation class ExplicitContainerRepeatable() { } diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.expected b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.expected new file mode 100644 index 00000000000..6ae3379e99f --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.expected @@ -0,0 +1,16 @@ +| JavaUser.java:9:14:9:21 | JavaUser | out2/JavaUser.class:0:0:0:0 | Container | value | out2/JavaUser.class:0:0:0:0 | {...} | +| JavaUser.java:9:14:9:21 | JavaUser | out2/JavaUser.class:0:0:0:0 | Container | value | out2/JavaUser.class:0:0:0:0 | {...} | +| JavaUser.java:9:14:9:21 | JavaUser | out2/JavaUser.class:0:0:0:0 | JavaDefinedContainer | value | out2/JavaUser.class:0:0:0:0 | {...} | +| JavaUser.java:9:14:9:21 | JavaUser | out2/JavaUser.class:0:0:0:0 | KtDefinedContainer | value | out2/JavaUser.class:0:0:0:0 | {...} | +| out/ExplicitContainerRepeatable.class:0:0:0:0 | ExplicitContainerRepeatable | out/ExplicitContainerRepeatable.class:0:0:0:0 | Repeatable | value | out/ExplicitContainerRepeatable.class:0:0:0:0 | KtDefinedContainer.class | +| out/ExplicitContainerRepeatable.class:0:0:0:0 | ExplicitContainerRepeatable | out/ExplicitContainerRepeatable.class:0:0:0:0 | Retention | value | out/ExplicitContainerRepeatable.class:0:0:0:0 | RUNTIME | +| out/JavaDefinedRepeatable.class:0:0:0:0 | JavaDefinedRepeatable | out/JavaDefinedRepeatable.class:0:0:0:0 | Repeatable | value | out/JavaDefinedRepeatable.class:0:0:0:0 | JavaDefinedContainer.class | +| out/KtDefinedContainer.class:0:0:0:0 | KtDefinedContainer | out/KtDefinedContainer.class:0:0:0:0 | Retention | value | out/KtDefinedContainer.class:0:0:0:0 | RUNTIME | +| out/LibRepeatable.class:0:0:0:0 | LibRepeatable | out/LibRepeatable.class:0:0:0:0 | Repeatable | value | out/LibRepeatable.class:0:0:0:0 | Container.class | +| out/LibRepeatable.class:0:0:0:0 | LibRepeatable | out/LibRepeatable.class:0:0:0:0 | Retention | value | out/LibRepeatable.class:0:0:0:0 | RUNTIME | +| test.kt:1:1:2:43 | LocalRepeatable | test.kt:0:0:0:0 | Repeatable | value | test.kt:0:0:0:0 | Container.class | +| test.kt:1:1:2:43 | LocalRepeatable | test.kt:0:0:0:0 | Retention | value | test.kt:0:0:0:0 | RetentionPolicy.RUNTIME | +| test.kt:4:1:12:21 | User | test.kt:0:0:0:0 | Container | value | test.kt:0:0:0:0 | {...} | +| test.kt:4:1:12:21 | User | test.kt:0:0:0:0 | Container | value | test.kt:0:0:0:0 | {...} | +| test.kt:4:1:12:21 | User | test.kt:0:0:0:0 | JavaDefinedContainer | value | test.kt:0:0:0:0 | {...} | +| test.kt:4:1:12:21 | User | test.kt:0:0:0:0 | KtDefinedContainer | value | test.kt:0:0:0:0 | {...} | diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.kt b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.kt new file mode 100644 index 00000000000..16a54a3e630 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.kt @@ -0,0 +1,12 @@ +@Repeatable +public annotation class LocalRepeatable { } + +@LocalRepeatable +@LocalRepeatable +@LibRepeatable +@LibRepeatable +@ExplicitContainerRepeatable +@ExplicitContainerRepeatable +@JavaDefinedRepeatable +@JavaDefinedRepeatable +public class User { } diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.py b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.py new file mode 100644 index 00000000000..e0b7c69cb05 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.py @@ -0,0 +1,7 @@ +from create_database_utils import * + +os.mkdir('out') +os.mkdir('out2') +runSuccessfully([get_cmd("kotlinc"), "lib.kt", "-d", "out"]) +runSuccessfully([get_cmd("javac"), "JavaDefinedContainer.java", "JavaDefinedRepeatable.java", "-d", "out"]) +run_codeql_database_create(["kotlinc test.kt -cp out -d out", "javac JavaUser.java -cp out -d out2"], lang="java") diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.ql b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.ql new file mode 100644 index 00000000000..701f6aed1ab --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.ql @@ -0,0 +1,11 @@ +import java + +from ClassOrInterface annotated, Annotation a, string valName, Expr val +where + a.getValue(valName) = val and + annotated = a.getAnnotatedElement() and + annotated.getName() in [ + "JavaDefinedRepeatable", "JavaDefinedContainer", "KtDefinedContainer", "LibRepeatable", + "ExplicitContainerRepeatable", "LocalRepeatable", "User", "JavaUser" + ] +select a.getAnnotatedElement(), a, valName, val diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected index 51186ef7b15..6921b7541ad 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected @@ -50,7 +50,7 @@ d.kt: # 1| 1: [Class] D # 0| 2: [FieldDeclaration] String bar; # 0| -1: [TypeAccess] String -# 0| 0: [StringLiteral] Foobar +# 0| 0: [StringLiteral] "Foobar" # 1| 3: [Constructor] D # 1| 5: [BlockStmt] { ... } # 1| 0: [SuperConstructorInvocationStmt] super(...) diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt index c88410ca9db..d80801974e2 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt @@ -4,7 +4,7 @@ import com.intellij.mock.MockProject import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext -import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.common.ir.addDispatchReceiver import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.typeWith +import org.jetbrains.kotlin.ir.util.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml new file mode 100644 index 00000000000..e2f6b6de7ba --- /dev/null +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml @@ -0,0 +1,3 @@ +name: integrationtest-custom-plugin +dependencies: + codeql/java-all: '*' diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected index 606bbd3f338..092e8241a3d 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected @@ -1 +1 @@ -| d.kt:0:0:0:0 | bar | d.kt:0:0:0:0 | Foobar | +| d.kt:0:0:0:0 | bar | d.kt:0:0:0:0 | "Foobar" | diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 696c3097fac..21b8949ce62 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.4.6 + +No user-facing changes. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +### New Features + +* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. +* The new `string Compilation.getInfo(string)` predicate provides access to some information about compilations. + +### Minor Analysis Improvements + +* The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. + ## 0.4.3 No user-facing changes. diff --git a/java/ql/lib/change-notes/2022-10-17-android-activity-alias.md b/java/ql/lib/change-notes/2022-10-17-android-activity-alias.md new file mode 100644 index 00000000000..c33a1feaaae --- /dev/null +++ b/java/ql/lib/change-notes/2022-10-17-android-activity-alias.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added support for Android Manifest `` elements in data flow sources. diff --git a/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md b/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md deleted file mode 100644 index 4716fb2ac41..00000000000 --- a/java/ql/lib/change-notes/2022-10-19-android-startactivities-summaries.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-11-10-kotlin-default.md b/java/ql/lib/change-notes/2022-11-10-kotlin-default.md deleted file mode 100644 index d411c58173c..00000000000 --- a/java/ql/lib/change-notes/2022-11-10-kotlin-default.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. diff --git a/java/ql/lib/change-notes/2022-11-17-deleted-deps.md b/java/ql/lib/change-notes/2022-11-17-deleted-deps.md new file mode 100644 index 00000000000..014b4ff23eb --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-17-deleted-deps.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `LocalClassDeclStmtNode` and `LocalClassDeclStmt` classes from `PrintAst.qll` and `Statement.qll` respectively. +* Deleted the deprecated `getLocalClass` predicate from `LocalTypeDeclStmt`, and the deprecated `getLocalClassDeclStmt` predicate from `LocalClassOrInterface`. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md b/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md new file mode 100644 index 00000000000..a586cecf04b --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-21-paths-get-fix.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added a taint model for the method `java.nio.file.Path.getParent`. +* Fixed a problem in the taint model for the method `java.nio.file.Paths.get`. diff --git a/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md b/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md new file mode 100644 index 00000000000..6e897ed60c2 --- /dev/null +++ b/java/ql/lib/change-notes/2022-11-23-mad-data-extensions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Models as Data models for Java are defined as data extensions instead of being inlined in the code. New models should be added in the `lib/ext` folder. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-12-05-insecure-cookie-global-flow.md b/java/ql/lib/change-notes/2022-12-05-insecure-cookie-global-flow.md new file mode 100644 index 00000000000..3eb33b8624e --- /dev/null +++ b/java/ql/lib/change-notes/2022-12-05-insecure-cookie-global-flow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/insecure-cookie` now uses global dataflow to track secure cookies being set to the HTTP response object. diff --git a/java/ql/lib/change-notes/2022-12-05-kotlin-path-sanitizer.md b/java/ql/lib/change-notes/2022-12-05-kotlin-path-sanitizer.md new file mode 100644 index 00000000000..ac6d59046a0 --- /dev/null +++ b/java/ql/lib/change-notes/2022-12-05-kotlin-path-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The library `PathSanitizer.qll` has been improved to detect more path validation patterns in Kotlin. diff --git a/java/ql/lib/change-notes/2022-12-09-default-extension-methods.md b/java/ql/lib/change-notes/2022-12-09-default-extension-methods.md new file mode 100644 index 00000000000..df9d23503da --- /dev/null +++ b/java/ql/lib/change-notes/2022-12-09-default-extension-methods.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The extraction of Kotlin extension methods has been improved when default parameter values are present. The dispatch and extension receiver parameters are extracted in the correct order. The `ExtensionMethod::getExtensionReceiverParameterIndex` predicate has been introduced to facilitate getting the correct extension parameter index. diff --git a/java/ql/lib/change-notes/released/0.4.4.md b/java/ql/lib/change-notes/released/0.4.4.md new file mode 100644 index 00000000000..ca76975d283 --- /dev/null +++ b/java/ql/lib/change-notes/released/0.4.4.md @@ -0,0 +1,11 @@ +## 0.4.4 + +### New Features + +* Kotlin support is now in beta. This means that Java analyses will also include Kotlin code by default. Kotlin support can be disabled by setting `CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN` to `true` in the environment. +* The new `string Compilation.getInfo(string)` predicate provides access to some information about compilations. + +### Minor Analysis Improvements + +* The ReDoS libraries in `semmle.code.java.security.regexp` has been moved to a shared pack inside the `shared/` folder, and the previous location has been deprecated. +* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`. diff --git a/java/ql/lib/change-notes/released/0.4.5.md b/java/ql/lib/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/java/ql/lib/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/java/ql/lib/change-notes/released/0.4.6.md b/java/ql/lib/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..8e652998eca --- /dev/null +++ b/java/ql/lib/change-notes/released/0.4.6.md @@ -0,0 +1,3 @@ +## 0.4.6 + +No user-facing changes. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 709f1d1fd04..44d61b266be 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -31,6 +31,12 @@ compilation_started( int id : @compilation ref ) +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + /** * The arguments that were passed to the extractor for a compiler * invocation. If `id` is for the compiler invocation diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats index 21f4ae2aa28..7ebc6e0b93e 100644 --- a/java/ql/lib/config/semmlecode.dbscheme.stats +++ b/java/ql/lib/config/semmlecode.dbscheme.stats @@ -6,11 +6,11 @@ @kotlincompilation - 6806 + 7683 @diagnostic - 631661 + 61632 @externalDataElement @@ -26,27 +26,27 @@ @file - 7997871 + 9158642 @folder - 1275575 + 1415670 @location_default - 430051334 + 602747369 @package - 611241 - - - @modifier - 13613 + 580098 @primitive - 12252 + 17287 + + + @modifier + 26891 @errortype @@ -54,87 +54,87 @@ @class - 12548830 + 12618104 @kt_nullable_type - 1361 + 1920 @kt_notnull_type - 191419 + 172391 @kt_type_alias - 2060 + 1821 @interface - 21501109 + 23200100 @fielddecl - 398872 + 199475 @field - 27509955 + 19350704 @constructor - 6869320 + 8006128 @method - 93308954 + 109719302 @param - 101015498 + 120852585 @exception - 1228169 + 1232644 @typevariable - 5105024 + 6288883 @wildcard - 3629331 + 3338447 @typebound - 4383514 + 4229725 @array - 1116298 + 1375332 @import - 368532 + 368550 @block - 845392 + 756817 @ifstmt - 188296 + 188285 @forstmt - 52508 + 52504 @enhancedforstmt - 18506 + 18520 @whilestmt - 21684 + 13266 @dostmt @@ -142,7 +142,7 @@ @trystmt - 58627 + 58624 @switchstmt @@ -150,19 +150,19 @@ @synchronizedstmt - 18703 + 18206 @returnstmt - 674863 + 532846 @throwstmt - 35919 + 35917 @breakstmt - 35331 + 35329 @continuestmt @@ -170,23 +170,23 @@ @emptystmt - 1562 + 1561 @exprstmt - 942161 + 942102 @assertstmt - 10816 + 10815 @localvariabledeclstmt - 318709 + 318689 @localtypedeclstmt - 4057 + 3841 @constructorinvocationstmt @@ -194,19 +194,19 @@ @superconstructorinvocationstmt - 223641 + 201354 @case - 107943 + 107945 @catchclause - 55205 + 55201 @labeledstmt - 2560 + 2342 @yieldstmt @@ -218,27 +218,27 @@ @whenbranch - 234276 + 225101 @arrayaccess - 409706 + 409681 @arraycreationexpr - 69251 + 69247 @arrayinit - 405408 + 405405 @assignexpr - 465437 + 465407 @assignaddexpr - 17017 + 17016 @assignsubexpr @@ -258,63 +258,63 @@ @assignorexpr - 14529 + 14528 @booleanliteral - 589884 + 589912 @integerliteral - 1151527 + 1151458 @longliteral - 185903 + 185904 @floatingpointliteral - 2825166 + 2824996 @doubleliteral - 486650 + 486619 @characterliteral - 40018 + 40016 @stringliteral - 1262892 + 1262818 @nullliteral - 355828 + 434113 @mulexpr - 204593 + 204580 @divexpr - 36267 + 36264 @remexpr - 3896 + 3904 @addexpr - 176997 + 176986 @subexpr - 84390 + 84385 @lshiftexpr - 8737 + 8736 @rshiftexpr @@ -326,11 +326,11 @@ @andbitexpr - 29091 + 110212 @orbitexpr - 8626 + 12590 @xorbitexpr @@ -338,47 +338,47 @@ @andlogicalexpr - 41339 + 36742 @orlogicalexpr - 31152 + 31150 @ltexpr - 66254 + 66249 @gtexpr - 17204 + 17203 @leexpr - 10530 + 10529 @geexpr - 13412 + 13411 @eqexpr - 104281 + 128429 @neexpr - 60978 + 60975 @postincexpr - 29634 + 29632 @postdecexpr - 11684 + 11683 @preincexpr - 23716 + 23714 @predecexpr @@ -386,75 +386,75 @@ @minusexpr - 744431 + 744386 @plusexpr - 53010 + 53007 @bitnotexpr - 8187 + 8186 @lognotexpr - 40113 + 40111 @castexpr - 93193 + 93187 @newexpr - 252099 + 252083 @conditionalexpr - 16048 + 16047 @instanceofexpr - 31040 + 29542 @localvariabledeclexpr - 385297 + 385272 @typeliteral - 148289 + 144350 @thisaccess - 949960 + 756915 @superaccess - 22195 + 99884 @varaccess - 2434432 + 2434277 @methodaccess - 1578817 + 1512385 @unannotatedtypeaccess - 2861937 + 2608638 @arraytypeaccess - 120735 + 120727 @wildcardtypeaccess - 63960 + 64091 @declannotation - 6745248 + 6740832 @assignremexpr @@ -462,7 +462,7 @@ @assignxorexpr - 1101 + 1102 @assignlshiftexpr @@ -490,19 +490,19 @@ @lambdaexpr - 183936 + 167982 @memberref - 23858 + 23859 @annotatedtypeaccess - 1280 + 1281 @typeannotation - 1280 + 1281 @intersectiontypeaccess @@ -518,43 +518,43 @@ @whenexpr - 172064 + 152111 @getclassexpr - 1361 + 1920 @safecastexpr - 6932 + 6402 @implicitcastexpr - 32918 + 30316 @implicitnotnullexpr - 241262 + 216630 @implicitcoerciontounitexpr - 91329 + 81396 @notinstanceofexpr - 19576 + 17306 @stmtexpr - 57687 + 55704 @stringtemplateexpr - 55814 + 59546 @notnullexpr - 20290 + 18820 @unsafecoerceexpr @@ -562,23 +562,23 @@ @valueeqexpr - 102712 + 93060 @valueneexpr - 108184 + 95639 @propertyref - 9642 + 8878 @localvar - 385297 + 385272 @module - 7964 + 7965 @requires @@ -586,7 +586,7 @@ @exports - 35011 + 35013 @opens @@ -594,7 +594,7 @@ @uses - 10785 + 10786 @provides @@ -602,15 +602,15 @@ @javadoc - 985153 + 985091 @javadocTag - 335830 + 335808 @javadocText - 2503007 + 2502848 @xmldtd @@ -618,23 +618,23 @@ @xmlelement - 106507143 + 150282022 @xmlattribute - 129551904 + 182798274 @xmlnamespace - 8168 + 11525 @xmlcomment - 107198704 + 151257816 @xmlcharacters - 101302741 + 142938589 @config @@ -650,15 +650,15 @@ @ktcomment - 133411 + 188243 @ktcommentsection - 59896 + 52611 @kt_property - 30236718 + 21895839 @@ -880,30 +880,146 @@ compilation_started - 6806 + 7683 id - 6806 + 7683 - compilation_args - 157915 + compilation_info + 15366 id - 6806 + 7683 + + + info_key + 3841 + + + info_value + 3841 + + + + + id + info_key + + + 12 + + + 2 + 3 + 7683 + + + + + + + id + info_value + + + 12 + + + 2 + 3 + 7683 + + + + + + + info_key + id + + + 12 + + + 4 + 5 + 3841 + + + + + + + info_key + info_value + + + 12 + + + 1 + 2 + 3841 + + + + + + + info_value + id + + + 12 + + + 4 + 5 + 3841 + + + + + + + info_value + info_key + + + 12 + + + 1 + 2 + 3841 + + + + + + + + + compilation_args + 169035 + + + id + 7683 num - 38117 + 48021 arg - 89848 + 90280 @@ -917,22 +1033,17 @@ 20 21 - 2722 + 3841 23 24 - 1361 + 1920 25 26 - 1361 - - - 28 - 29 - 1361 + 1920 @@ -948,22 +1059,17 @@ 20 21 - 2722 + 3841 23 24 - 1361 + 1920 25 26 - 1361 - - - 27 - 28 - 1361 + 1920 @@ -979,22 +1085,17 @@ 1 2 - 4084 + 3841 2 3 - 2722 + 5762 - 3 - 4 - 4084 - - - 5 - 6 - 27226 + 4 + 5 + 38417 @@ -1010,27 +1111,22 @@ 1 2 - 8168 + 9604 2 3 - 5445 + 17287 3 4 - 10890 + 11525 4 5 - 6806 - - - 5 - 6 - 6806 + 9604 @@ -1046,22 +1142,17 @@ 1 2 - 69428 + 61467 2 3 - 2722 + 3841 4 5 - 6806 - - - 5 - 6 - 10890 + 24971 @@ -1077,17 +1168,17 @@ 1 2 - 72151 + 67229 2 3 - 14974 + 19208 - 4 - 5 - 2722 + 3 + 4 + 3841 @@ -1097,19 +1188,19 @@ compilation_compiling_files - 61119 + 59495 id - 2337 + 2275 num - 18035 + 17556 file - 51099 + 49742 @@ -1123,22 +1214,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1154,22 +1245,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1185,17 +1276,17 @@ 2 3 - 6345 + 6177 4 5 - 11021 + 10728 6 8 - 667 + 650 @@ -1211,17 +1302,17 @@ 2 3 - 6345 + 6177 3 4 - 10019 + 9753 4 8 - 1669 + 1625 @@ -1237,12 +1328,12 @@ 1 2 - 41080 + 39989 2 3 - 10019 + 9753 @@ -1258,7 +1349,7 @@ 1 2 - 51099 + 49742 @@ -1268,19 +1359,19 @@ compilation_compiling_files_completed - 61119 + 59495 id - 2337 + 2275 num - 18035 + 17556 result - 667 + 325 @@ -1294,22 +1385,22 @@ 1 2 - 333 + 325 2 3 - 667 + 650 35 36 - 667 + 650 54 55 - 667 + 650 @@ -1325,12 +1416,7 @@ 1 2 - 1669 - - - 2 - 3 - 667 + 2275 @@ -1346,17 +1432,17 @@ 2 3 - 6345 + 6177 4 5 - 11021 + 10728 6 8 - 667 + 650 @@ -1372,12 +1458,7 @@ 1 2 - 17701 - - - 2 - 3 - 333 + 17556 @@ -1390,15 +1471,10 @@ 12 - - 2 - 3 - 333 - 7 8 - 333 + 325 @@ -1411,15 +1487,10 @@ 12 - - 1 - 2 - 333 - 54 55 - 333 + 325 @@ -1429,7 +1500,7 @@ compilation_time - 196462 + 196471 id @@ -1437,7 +1508,7 @@ num - 5143 + 5144 kind @@ -1445,7 +1516,7 @@ seconds - 89768 + 89772 @@ -1658,7 +1729,7 @@ 4 5 - 5143 + 5144 @@ -1793,7 +1864,7 @@ 1 2 - 89602 + 89606 52 @@ -1814,7 +1885,7 @@ 1 2 - 89602 + 89606 31 @@ -1835,7 +1906,7 @@ 1 2 - 89602 + 89606 3 @@ -1850,23 +1921,23 @@ diagnostic_for - 631661 + 61632 diagnostic - 631661 + 61632 compilation - 6806 + 574 file_number - 8168 + 14797 file_number_diagnostic_number - 59898 + 2154 @@ -1880,7 +1951,7 @@ 1 2 - 631661 + 61632 @@ -1896,7 +1967,7 @@ 1 2 - 631661 + 61632 @@ -1912,7 +1983,7 @@ 1 2 - 631661 + 61632 @@ -1926,24 +1997,24 @@ 12 - 73 - 74 - 1361 + 14 + 15 + 143 - 84 - 85 - 1361 + 28 + 29 + 143 - 100 - 101 - 2722 + 123 + 124 + 143 - 107 - 108 - 1361 + 264 + 265 + 143 @@ -1957,24 +2028,24 @@ 12 - 3 - 4 - 2722 + 7 + 8 + 143 - 4 - 5 - 1361 + 14 + 15 + 143 - 5 - 6 - 1361 + 45 + 46 + 143 - 6 - 7 - 1361 + 103 + 104 + 143 @@ -1988,29 +2059,19 @@ 12 - 29 - 30 - 1361 + 2 + 3 + 287 - 34 - 35 - 1361 + 14 + 15 + 143 - 40 - 41 - 1361 - - - 42 - 43 - 1361 - - - 44 - 45 - 1361 + 15 + 16 + 143 @@ -2019,47 +2080,6 @@ file_number diagnostic - - - 12 - - - 6 - 7 - 1361 - - - 35 - 36 - 1361 - - - 49 - 50 - 1361 - - - 101 - 102 - 1361 - - - 129 - 130 - 1361 - - - 144 - 145 - 1361 - - - - - - - file_number - compilation 12 @@ -2067,22 +2087,73 @@ 1 2 - 1361 + 143 2 3 - 1361 + 6464 3 4 - 1361 + 718 + + + 4 + 5 + 3160 5 6 - 4084 + 1292 + + + 6 + 8 + 1149 + + + 8 + 11 + 1292 + + + 12 + 21 + 574 + + + + + + + file_number + compilation + + + 12 + + + 1 + 2 + 8332 + + + 2 + 3 + 4453 + + + 3 + 4 + 1005 + + + 4 + 5 + 1005 @@ -2096,34 +2167,34 @@ 12 - 6 - 7 - 1361 + 1 + 2 + 143 - 15 + 2 + 3 + 10056 + + + 3 + 4 + 2011 + + + 4 + 5 + 1005 + + + 5 + 8 + 1149 + + + 10 16 - 1361 - - - 34 - 35 - 1361 - - - 40 - 41 - 1361 - - - 42 - 43 - 1361 - - - 44 - 45 - 1361 + 430 @@ -2138,58 +2209,53 @@ 1 - 3 - 5445 + 2 + 143 - 4 - 5 - 6806 + 2 + 3 + 574 + + + 3 + 4 + 430 5 6 - 1361 + 143 7 8 - 6806 + 143 - 8 - 9 - 4084 - - - 9 - 10 - 9529 - - - 10 - 14 - 5445 - - - 15 - 16 - 2722 - - - 16 - 17 - 8168 + 11 + 12 + 143 18 - 20 - 4084 + 19 + 143 - 20 - 22 - 5445 + 33 + 34 + 143 + + + 168 + 169 + 143 + + + 169 + 170 + 143 @@ -2204,23 +2270,18 @@ 1 - 3 - 5445 + 2 + 143 - 3 - 4 - 8168 + 2 + 3 + 1723 4 5 - 6806 - - - 5 - 6 - 39478 + 287 @@ -2235,28 +2296,53 @@ 1 + 2 + 143 + + + 2 3 - 5445 + 574 3 4 - 8168 - - - 4 - 5 - 25865 + 430 5 6 - 12252 + 143 - 6 - 7 - 8168 + 7 + 8 + 143 + + + 11 + 12 + 143 + + + 18 + 19 + 143 + + + 32 + 33 + 143 + + + 102 + 103 + 143 + + + 103 + 104 + 143 @@ -2266,19 +2352,19 @@ compilation_compiler_times - 6806 + 7683 id - 6806 + 7683 cpu_seconds - 1361 + 1920 elapsed_seconds - 6806 + 7683 @@ -2292,7 +2378,7 @@ 1 2 - 6806 + 7683 @@ -2308,7 +2394,7 @@ 1 2 - 6806 + 7683 @@ -2322,9 +2408,9 @@ 12 - 5 - 6 - 1361 + 4 + 5 + 1920 @@ -2338,9 +2424,9 @@ 12 - 5 - 6 - 1361 + 4 + 5 + 1920 @@ -2356,7 +2442,7 @@ 1 2 - 6806 + 7683 @@ -2372,7 +2458,7 @@ 1 2 - 6806 + 7683 @@ -2598,35 +2684,35 @@ diagnostics - 631661 + 61632 id - 631661 + 61632 generated_by - 1361 + 143 severity - 1361 + 143 error_tag - 1361 + 143 error_message - 96655 + 1580 full_error_message - 520031 + 40944 location - 1361 + 143 @@ -2640,7 +2726,7 @@ 1 2 - 631661 + 61632 @@ -2656,7 +2742,7 @@ 1 2 - 631661 + 61632 @@ -2672,7 +2758,7 @@ 1 2 - 631661 + 61632 @@ -2688,7 +2774,7 @@ 1 2 - 631661 + 61632 @@ -2704,7 +2790,7 @@ 1 2 - 631661 + 61632 @@ -2720,7 +2806,7 @@ 1 2 - 631661 + 61632 @@ -2734,9 +2820,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2752,7 +2838,7 @@ 1 2 - 1361 + 143 @@ -2768,7 +2854,7 @@ 1 2 - 1361 + 143 @@ -2782,9 +2868,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2798,9 +2884,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -2816,7 +2902,7 @@ 1 2 - 1361 + 143 @@ -2830,9 +2916,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2848,7 +2934,7 @@ 1 2 - 1361 + 143 @@ -2864,7 +2950,7 @@ 1 2 - 1361 + 143 @@ -2878,9 +2964,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2894,9 +2980,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -2912,7 +2998,7 @@ 1 2 - 1361 + 143 @@ -2926,9 +3012,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -2944,7 +3030,7 @@ 1 2 - 1361 + 143 @@ -2960,7 +3046,7 @@ 1 2 - 1361 + 143 @@ -2974,9 +3060,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -2990,9 +3076,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -3008,7 +3094,7 @@ 1 2 - 1361 + 143 @@ -3024,62 +3110,47 @@ 1 2 - 19058 + 143 2 3 - 5445 + 143 3 4 - 12252 - - - 4 - 5 - 5445 - - - 5 - 6 - 5445 + 143 6 7 - 8168 - - - 7 - 8 - 2722 - - - 8 - 9 - 9529 + 143 9 10 - 6806 + 143 - 10 - 11 - 8168 + 12 + 13 + 287 - 14 - 17 - 6806 + 24 + 25 + 143 - 17 - 21 - 6806 + 28 + 29 + 143 + + + 166 + 167 + 287 @@ -3095,7 +3166,7 @@ 1 2 - 96655 + 1580 @@ -3111,7 +3182,7 @@ 1 2 - 96655 + 1580 @@ -3127,7 +3198,7 @@ 1 2 - 96655 + 1580 @@ -3143,57 +3214,52 @@ 1 2 - 21781 + 143 2 3 - 5445 + 143 3 4 - 12252 - - - 4 - 5 - 5445 - - - 5 - 6 - 4084 + 143 6 7 - 8168 - - - 7 - 8 - 12252 - - - 8 - 9 - 6806 + 143 9 - 11 - 8168 - - - 11 - 12 - 6806 + 10 + 143 12 - 14 - 5445 + 13 + 287 + + + 22 + 23 + 143 + + + 24 + 25 + 143 + + + 28 + 29 + 143 + + + 166 + 167 + 143 @@ -3209,7 +3275,7 @@ 1 2 - 96655 + 1580 @@ -3225,17 +3291,12 @@ 1 2 - 441074 + 38358 2 - 3 - 51730 - - - 3 - 5 - 27226 + 25 + 2585 @@ -3251,7 +3312,7 @@ 1 2 - 520031 + 40944 @@ -3267,7 +3328,7 @@ 1 2 - 520031 + 40944 @@ -3283,7 +3344,7 @@ 1 2 - 520031 + 40944 @@ -3299,7 +3360,7 @@ 1 2 - 520031 + 40944 @@ -3315,7 +3376,7 @@ 1 2 - 520031 + 40944 @@ -3329,9 +3390,9 @@ 12 - 464 - 465 - 1361 + 429 + 430 + 143 @@ -3347,7 +3408,7 @@ 1 2 - 1361 + 143 @@ -3363,7 +3424,7 @@ 1 2 - 1361 + 143 @@ -3379,7 +3440,7 @@ 1 2 - 1361 + 143 @@ -3393,9 +3454,9 @@ 12 - 71 - 72 - 1361 + 11 + 12 + 143 @@ -3409,9 +3470,9 @@ 12 - 382 - 383 - 1361 + 285 + 286 + 143 @@ -3576,11 +3637,11 @@ sourceLocationPrefix - 1361 + 1920 prefix - 1361 + 1920 @@ -4867,31 +4928,31 @@ locations_default - 430051334 + 602747369 id - 430051334 + 602747369 file - 7997871 + 9158642 beginLine - 2794830 + 3943517 beginColumn - 175612 + 247790 endLine - 2796191 + 3945438 endColumn - 619409 + 873989 @@ -4905,7 +4966,7 @@ 1 2 - 430051334 + 602747369 @@ -4921,7 +4982,7 @@ 1 2 - 430051334 + 602747369 @@ -4937,7 +4998,7 @@ 1 2 - 430051334 + 602747369 @@ -4953,7 +5014,7 @@ 1 2 - 430051334 + 602747369 @@ -4969,7 +5030,7 @@ 1 2 - 430051334 + 602747369 @@ -4985,17 +5046,17 @@ 1 2 - 7159286 + 7986919 2 - 20 - 603073 + 11 + 714558 - 20 + 11 3605 - 235511 + 457163 @@ -5011,17 +5072,17 @@ 1 2 - 7159286 + 7986919 2 - 15 - 600350 + 9 + 712637 - 15 + 9 1830 - 238234 + 459084 @@ -5037,17 +5098,17 @@ 1 2 - 7159286 + 7986919 2 - 7 - 627577 + 5 + 776025 - 7 + 5 105 - 211007 + 395696 @@ -5063,17 +5124,17 @@ 1 2 - 7159286 + 7986919 2 - 18 - 600350 + 10 + 693429 - 18 + 10 1834 - 238234 + 478293 @@ -5089,17 +5150,17 @@ 1 2 - 7159286 + 7986919 2 - 15 - 603073 + 9 + 695349 - 15 + 9 205 - 235511 + 476372 @@ -5115,67 +5176,67 @@ 1 14 - 221898 + 313099 14 125 - 215091 + 301574 125 142 - 215091 + 307336 142 152 - 223259 + 316941 152 159 - 249125 + 359200 159 - 165 - 257293 + 164 + 272761 - 165 - 170 - 225982 + 164 + 169 + 343833 - 170 - 174 - 216453 + 169 + 173 + 299653 - 174 - 179 - 228705 + 173 + 178 + 332308 - 179 - 185 - 213730 + 178 + 184 + 347674 - 185 - 194 - 221898 + 184 + 193 + 316941 - 194 - 215 - 215091 + 193 + 211 + 297732 - 215 - 5876 - 91209 + 211 + 4769 + 134459 @@ -5191,67 +5252,72 @@ 1 7 - 228705 + 322703 7 65 - 212369 + 299653 65 73 - 216453 + 307336 73 78 - 206923 + 295811 78 81 - 190587 + 265078 81 84 - 249125 + 357279 84 86 - 215091 + 299653 86 - 88 - 257293 + 87 + 188243 - 88 - 90 - 221898 + 87 + 89 + 357279 - 90 - 93 - 247763 + 89 + 91 + 259315 - 93 - 97 - 217814 + 91 + 94 + 324624 - 97 - 106 - 213730 + 94 + 99 + 328466 - 106 - 5876 - 117075 + 99 + 141 + 295811 + + + 141 + 4769 + 42258 @@ -5267,62 +5333,62 @@ 1 5 - 221898 + 313099 5 17 - 196032 + 280444 17 19 - 167444 + 251632 19 20 - 213730 + 309257 20 21 - 268183 + 403379 21 22 - 283158 + 420667 22 23 - 329444 + 476372 23 24 - 303578 + 457163 24 25 - 235511 + 339991 25 26 - 170167 + 213215 26 - 28 - 212369 + 29 + 361120 - 28 - 45 - 193310 + 29 + 40 + 117172 @@ -5338,32 +5404,32 @@ 1 2 - 902568 + 1273527 2 3 - 894400 + 1265844 3 4 - 481914 + 674220 4 5 - 211007 + 299653 5 11 - 220537 + 307336 11 97 - 84403 + 122934 @@ -5379,72 +5445,72 @@ 1 13 - 219175 + 309257 13 60 - 209646 + 307336 60 64 - 223259 + 311178 64 66 - 209646 + 311178 66 68 - 258654 + 353437 68 69 - 130688 + 194006 69 70 - 155192 + 217056 70 - 71 - 134772 + 72 + 359200 - 71 - 73 - 235511 + 72 + 74 + 322703 - 73 - 75 - 212369 + 74 + 76 + 245869 - 75 - 78 - 234150 + 76 + 79 + 330387 - 78 - 82 - 251847 + 79 + 83 + 295811 - 82 - 89 - 213730 + 83 + 91 + 316941 - 89 - 104 - 106184 + 91 + 103 + 69150 @@ -5460,67 +5526,67 @@ 1 11 - 14974 + 21129 15 - 34 - 14974 + 24 + 21129 - 36 - 58 - 13613 + 28 + 57 + 19208 - 63 - 88 - 13613 + 57 + 79 + 19208 - 89 - 132 - 13613 + 87 + 119 + 19208 - 141 - 196 - 14974 + 130 + 177 + 19208 - 210 - 285 - 13613 + 195 + 269 + 19208 - 316 - 468 - 13613 + 270 + 436 + 19208 - 496 - 853 - 13613 + 443 + 835 + 19208 - 899 - 1420 - 13613 + 844 + 1367 + 19208 - 1472 - 2256 - 13613 + 1419 + 2155 + 19208 - 2300 - 2526 - 13613 + 2252 + 2517 + 19208 - 2589 - 226687 - 8168 + 2521 + 226452 + 13445 @@ -5536,72 +5602,72 @@ 1 9 - 9529 + 17287 9 11 - 13613 + 21129 - 12 - 16 - 8168 + 11 + 15 + 15366 - 16 + 15 19 - 13613 + 21129 - 19 - 31 - 13613 + 23 + 68 + 19208 - 35 - 73 - 13613 + 69 + 78 + 19208 - 73 - 83 - 13613 + 79 + 100 + 13445 - 85 + 100 104 - 14974 + 21129 104 - 110 - 10890 + 109 + 19208 - 110 - 114 - 14974 + 109 + 112 + 13445 + + + 112 + 115 + 19208 115 - 119 - 13613 + 117 + 19208 - 119 - 121 - 12252 + 117 + 123 + 19208 - 121 - 126 - 13613 - - - 126 - 5876 - 9529 + 145 + 4769 + 9604 @@ -5617,67 +5683,67 @@ 1 10 - 14974 + 21129 10 - 29 - 13613 + 22 + 21129 - 29 - 43 - 13613 + 23 + 39 + 19208 - 45 + 41 58 - 13613 + 19208 58 - 85 - 13613 + 84 + 19208 - 86 + 84 106 - 13613 + 19208 108 - 167 - 13613 + 166 + 19208 - 171 - 227 - 13613 + 167 + 225 + 19208 - 231 - 379 - 13613 + 230 + 376 + 19208 - 383 - 650 - 13613 + 381 + 647 + 19208 - 651 - 891 - 13613 + 657 + 941 + 19208 - 940 - 1086 - 13613 + 941 + 1090 + 19208 - 1093 + 1102 2051 - 10890 + 13445 @@ -5693,67 +5759,67 @@ 1 10 - 14974 + 21129 10 - 30 - 13613 + 22 + 21129 - 30 - 43 - 13613 + 23 + 39 + 19208 - 46 + 41 59 - 13613 + 19208 - 60 - 87 - 13613 + 59 + 86 + 19208 - 87 + 86 109 - 13613 + 19208 - 115 - 173 - 13613 + 114 + 168 + 19208 - 174 - 226 - 13613 + 170 + 224 + 19208 - 230 - 380 - 13613 + 229 + 379 + 19208 - 383 - 650 - 13613 + 382 + 647 + 19208 - 653 - 892 - 13613 + 658 + 941 + 19208 - 940 - 1084 - 13613 + 941 + 1089 + 19208 - 1092 + 1102 2051 - 10890 + 13445 @@ -5769,72 +5835,67 @@ 1 8 - 14974 + 21129 8 - 17 - 13613 + 16 + 21129 - 18 - 25 - 10890 + 16 + 23 + 21129 - 25 - 30 - 13613 + 24 + 31 + 21129 - 30 - 36 - 13613 + 32 + 37 + 21129 - 36 - 44 - 13613 + 37 + 50 + 19208 - 45 - 56 - 12252 + 50 + 60 + 19208 - 57 - 64 - 13613 + 60 + 68 + 19208 - 64 - 73 - 13613 + 68 + 80 + 19208 - 73 - 86 - 13613 + 81 + 101 + 19208 - 86 - 106 - 13613 + 101 + 121 + 19208 - 107 - 129 - 13613 + 126 + 158 + 19208 - 129 - 197 - 13613 - - - 392 + 159 393 - 1361 + 7683 @@ -5850,67 +5911,67 @@ 1 14 - 220537 + 309257 14 124 - 215091 + 305416 124 143 - 217814 + 309257 143 152 - 235511 + 334228 152 159 - 223259 + 322703 159 - 165 - 257293 + 164 + 299653 - 165 - 170 - 239595 + 164 + 169 + 341912 - 170 - 174 - 221898 + 169 + 173 + 309257 - 174 - 179 - 221898 + 173 + 178 + 338070 - 179 - 185 - 211007 + 178 + 184 + 305416 - 185 - 194 - 216453 + 184 + 193 + 315020 - 194 - 217 - 212369 + 193 + 212 + 301574 - 217 - 5876 - 103461 + 212 + 4769 + 153668 @@ -5926,67 +5987,67 @@ 1 7 - 231427 + 324624 7 66 - 224621 + 318862 66 74 - 227343 + 320782 74 80 - 250486 + 355358 80 83 - 240957 + 339991 83 85 - 185142 + 268919 85 87 - 246402 + 343833 87 89 - 246402 + 355358 89 91 - 187864 + 266999 91 94 - 247763 + 345754 94 99 - 225982 + 324624 99 - 127 - 212369 + 130 + 301574 - 127 - 5876 - 69428 + 131 + 4769 + 78755 @@ -6002,32 +6063,32 @@ 1 2 - 709258 + 1000766 2 3 - 986971 + 1392620 3 4 - 642552 + 908564 4 6 - 236873 + 336149 6 - 18 - 212369 + 19 + 299653 - 18 + 19 22 - 8168 + 7683 @@ -6043,62 +6104,62 @@ 1 5 - 219175 + 309257 5 17 - 198755 + 284286 17 19 - 163360 + 232423 19 20 - 191948 + 280444 20 21 - 280436 + 420667 21 22 - 272267 + 407221 22 23 - 329444 + 482134 23 24 - 306301 + 437955 24 25 - 224621 + 334228 25 26 - 183780 + 259315 26 - 28 - 223259 + 29 + 363041 - 28 - 44 - 202839 + 29 + 39 + 134459 @@ -6114,72 +6175,72 @@ 1 13 - 221898 + 313099 13 - 61 - 250486 + 60 + 305416 - 61 + 60 64 - 172890 + 305416 64 66 - 217814 + 303495 66 68 - 250486 + 357279 68 69 - 137495 + 197848 69 70 - 137495 + 201689 70 71 - 157915 + 218977 71 73 - 231427 + 326545 73 75 - 191948 + 263157 75 77 - 183780 + 257394 77 80 - 211007 + 299653 80 85 - 227343 + 318862 85 119 - 204200 + 276603 @@ -6195,57 +6256,57 @@ 1 2 - 145663 + 205531 2 3 - 63982 + 90280 3 5 - 50369 + 71071 5 13 - 50369 + 71071 13 53 - 47646 + 67229 53 - 146 - 47646 + 138 + 67229 - 146 - 351 - 47646 + 142 + 346 + 67229 357 - 997 - 47646 + 967 + 67229 - 1053 - 2396 - 47646 + 1050 + 2386 + 67229 - 2407 - 4957 - 47646 + 2392 + 4902 + 67229 - 5022 - 5934 - 23142 + 4949 + 5933 + 32654 @@ -6261,57 +6322,57 @@ 1 2 - 151108 + 213215 2 3 - 61260 + 86438 3 5 - 53092 + 74913 5 13 - 50369 + 71071 13 42 - 47646 + 67229 42 77 - 47646 + 67229 77 - 103 - 51730 + 102 + 69150 - 103 - 116 - 47646 + 102 + 114 + 67229 - 116 - 144 - 49008 + 114 + 139 + 67229 - 144 - 181 - 47646 + 139 + 169 + 69150 - 181 - 5876 - 12252 + 173 + 4769 + 21129 @@ -6327,57 +6388,57 @@ 1 2 - 153831 + 217056 2 3 - 62621 + 88359 3 5 - 49008 + 69150 5 13 - 49008 + 69150 13 - 52 - 49008 + 50 + 67229 - 52 - 115 - 47646 + 50 + 113 + 67229 - 123 - 271 - 47646 + 114 + 266 + 67229 - 272 - 658 - 47646 + 269 + 636 + 67229 - 669 - 1200 - 47646 + 648 + 1197 + 67229 - 1219 + 1198 1635 - 47646 + 69150 1639 1722 - 17697 + 24971 @@ -6393,47 +6454,47 @@ 1 2 - 194671 + 274682 2 3 - 74873 + 105647 3 6 - 54453 + 76834 6 14 - 54453 + 76834 14 - 26 - 47646 + 25 + 74913 - 26 + 25 36 - 49008 + 71071 36 47 - 49008 + 67229 47 - 55 - 47646 + 54 + 67229 - 55 - 68 - 47646 + 54 + 65 + 59546 @@ -6449,57 +6510,57 @@ 1 2 - 153831 + 217056 2 3 - 61260 + 86438 3 5 - 49008 + 69150 5 13 - 49008 + 69150 13 - 53 - 50369 + 51 + 67229 - 53 - 115 - 47646 + 51 + 112 + 67229 - 123 - 271 - 47646 + 112 + 262 + 67229 - 280 - 656 - 47646 + 262 + 630 + 67229 - 669 - 1200 - 47646 + 637 + 1186 + 67229 - 1217 - 1638 - 47646 + 1197 + 1625 + 67229 - 1640 + 1632 1722 - 17697 + 28812 @@ -6509,15 +6570,15 @@ hasLocation - 316413492 + 340930835 locatableid - 316270551 + 340658074 id - 11518296 + 12195515 @@ -6531,12 +6592,12 @@ 1 2 - 316127611 + 340385312 2 3 - 142940 + 272761 @@ -6552,62 +6613,57 @@ 1 2 - 2084211 + 2091812 2 3 - 996500 + 1333074 3 4 - 716064 + 772184 4 6 - 984248 + 1085283 6 - 7 - 771879 + 8 + 1062233 - 7 - 9 - 1014198 + 8 + 11 + 1100650 - 9 - 12 - 848114 + 11 + 15 + 1048787 - 12 - 16 - 928433 + 15 + 21 + 964269 - 16 - 23 - 868534 + 21 + 32 + 916248 - 23 - 39 - 894400 + 32 + 64 + 920090 - 39 - 89 - 873980 - - - 89 - 9992 - 537729 + 64 + 9549 + 900881 @@ -6617,23 +6673,23 @@ numlines - 214506316 + 303305105 element_id - 214506316 + 303305105 num_lines - 431544 + 618515 num_code - 432906 + 612753 num_comment - 1342281 + 1893964 @@ -6647,7 +6703,7 @@ 1 2 - 214506316 + 303305105 @@ -6663,7 +6719,7 @@ 1 2 - 214506316 + 303305105 @@ -6679,7 +6735,7 @@ 1 2 - 214506316 + 303305105 @@ -6695,37 +6751,37 @@ 1 2 - 231427 + 320782 2 3 - 53092 + 78755 3 4 - 44924 + 61467 4 7 - 34033 + 49942 7 14 - 32672 + 48021 15 - 839 - 32672 + 194 + 48021 - 3519 - 149603 - 2722 + 320 + 149659 + 11525 @@ -6741,12 +6797,17 @@ 1 2 - 422015 + 509026 2 3 - 9529 + 69150 + + + 3 + 6 + 40337 @@ -6762,27 +6823,27 @@ 1 2 - 273629 + 380329 2 3 - 69428 + 97963 3 4 - 36756 + 51863 4 6 - 34033 + 53783 6 987 - 17697 + 34575 @@ -6798,37 +6859,37 @@ 1 2 - 231427 + 316941 2 3 - 53092 + 78755 3 4 - 44924 + 61467 4 7 - 34033 + 51863 7 - 14 - 32672 + 15 + 46100 - 15 - 468 - 32672 + 16 + 214 + 46100 - 495 + 325 78746 - 4084 + 11525 @@ -6844,12 +6905,17 @@ 1 2 - 431544 + 516710 - 7 + 2 + 3 + 51863 + + + 3 8 - 1361 + 44179 @@ -6865,27 +6931,27 @@ 1 2 - 273629 + 370725 2 3 - 69428 + 101805 3 4 - 36756 + 53783 4 6 - 34033 + 46100 6 987 - 19058 + 40337 @@ -6901,77 +6967,77 @@ 1 7 - 108907 + 153668 7 49 - 100739 + 142143 49 71 - 104823 + 147905 71 78 - 107545 + 151747 78 83 - 103461 + 145985 83 87 - 115713 + 163272 87 89 - 99377 + 140222 89 91 - 95293 + 134459 91 92 - 57176 + 80675 92 93 - 68066 + 96042 93 94 - 74873 + 105647 94 95 - 69428 + 97963 95 97 - 108907 + 151747 97 119 - 100739 + 144064 - 119 - 75115 - 27226 + 120 + 75134 + 38417 @@ -6987,22 +7053,22 @@ 1 2 - 1101323 + 1550130 2 3 - 114352 + 165193 3 - 6 - 102100 + 7 + 145985 - 6 + 7 120 - 24504 + 32654 @@ -7018,22 +7084,22 @@ 1 2 - 1101323 + 1550130 2 3 - 114352 + 165193 3 - 6 - 100739 + 7 + 145985 - 6 - 121 - 25865 + 7 + 122 + 32654 @@ -7043,15 +7109,15 @@ files - 7997871 + 9158642 id - 7997871 + 9158642 name - 7997871 + 9158642 @@ -7065,7 +7131,7 @@ 1 2 - 7997871 + 9158642 @@ -7081,7 +7147,7 @@ 1 2 - 7997871 + 9158642 @@ -7091,15 +7157,15 @@ folders - 1275575 + 1415670 id - 1275575 + 1415670 name - 1275575 + 1415670 @@ -7113,7 +7179,7 @@ 1 2 - 1275575 + 1415670 @@ -7129,7 +7195,7 @@ 1 2 - 1275575 + 1415670 @@ -7139,15 +7205,15 @@ containerparent - 9270724 + 10570471 parent - 1316415 + 1463692 child - 9270724 + 10570471 @@ -7161,37 +7227,32 @@ 1 2 - 710619 + 843255 2 3 - 140218 + 149826 3 - 4 - 78957 + 5 + 128697 - 4 - 7 - 112991 + 5 + 11 + 124855 - 7 - 14 - 111629 + 11 + 21 + 113330 - 14 - 29 - 102100 - - - 29 + 21 194 - 59898 + 103726 @@ -7207,7 +7268,7 @@ 1 2 - 9270724 + 10570471 @@ -7217,15 +7278,15 @@ cupackage - 7140227 + 7979236 id - 7140227 + 7979236 packageid - 609880 + 576256 @@ -7239,7 +7300,7 @@ 1 2 - 7140227 + 7979236 @@ -7255,52 +7316,52 @@ 1 2 - 148386 + 121013 2 3 - 80319 + 80675 3 4 - 55814 + 42258 4 - 5 - 42201 + 6 + 49942 - 5 - 7 - 46285 + 6 + 9 + 49942 - 7 - 10 - 50369 + 9 + 12 + 51863 - 10 - 15 - 50369 + 12 + 17 + 48021 - 15 - 21 - 49008 + 17 + 23 + 46100 - 21 - 36 - 47646 + 24 + 43 + 44179 - 39 + 43 187 - 39478 + 42258 @@ -7310,19 +7371,19 @@ jarManifestMain - 172733 + 172742 fileid - 13274 + 13275 keyName - 12610 + 12611 value - 89768 + 89772 @@ -7407,7 +7468,7 @@ 5 6 - 2488 + 2489 6 @@ -7473,7 +7534,7 @@ 1 2 - 5143 + 5144 2 @@ -7580,7 +7641,7 @@ 1 2 - 75996 + 75999 2 @@ -7611,7 +7672,7 @@ 1 2 - 75664 + 75668 2 @@ -7621,7 +7682,7 @@ 3 6 - 5309 + 5310 @@ -7844,7 +7905,7 @@ 1 2 - 30112 + 30113 2 @@ -7886,7 +7947,7 @@ 1 2 - 30124 + 30125 3 @@ -8005,7 +8066,7 @@ 1 2 - 30161 + 30162 2 @@ -8026,7 +8087,7 @@ 1 2 - 30161 + 30162 11 @@ -8062,15 +8123,15 @@ packages - 611241 + 580098 id - 611241 + 580098 nodeName - 611241 + 580098 @@ -8084,7 +8145,7 @@ 1 2 - 611241 + 580098 @@ -8100,7 +8161,7 @@ 1 2 - 611241 + 580098 @@ -8110,15 +8171,15 @@ primitives - 12252 + 17287 id - 12252 + 17287 nodeName - 12252 + 17287 @@ -8132,7 +8193,7 @@ 1 2 - 12252 + 17287 @@ -8148,7 +8209,7 @@ 1 2 - 12252 + 17287 @@ -8158,15 +8219,15 @@ modifiers - 13613 + 26891 id - 13613 + 26891 nodeName - 13613 + 26891 @@ -8180,7 +8241,7 @@ 1 2 - 13613 + 26891 @@ -8196,7 +8257,7 @@ 1 2 - 13613 + 26891 @@ -8217,23 +8278,23 @@ classes - 12548830 + 12618104 id - 12548830 + 12618104 nodeName - 6855707 + 6732600 parentid - 442435 + 455242 sourceid - 4506034 + 5253541 @@ -8247,7 +8308,7 @@ 1 2 - 12548830 + 12618104 @@ -8263,7 +8324,7 @@ 1 2 - 12548830 + 12618104 @@ -8279,7 +8340,7 @@ 1 2 - 12548830 + 12618104 @@ -8295,17 +8356,17 @@ 1 2 - 5728517 + 5601216 2 3 - 741930 + 726083 3 - 236 - 385259 + 204 + 405300 @@ -8321,17 +8382,17 @@ 1 2 - 6243104 + 5950812 2 3 - 544535 + 731846 3 52 - 68066 + 49942 @@ -8347,17 +8408,17 @@ 1 2 - 6219961 + 5921999 2 3 - 533645 + 714558 3 160 - 102100 + 96042 @@ -8373,57 +8434,62 @@ 1 2 - 107545 + 94121 2 3 - 54453 + 46100 3 4 - 32672 + 30733 4 5 - 29949 + 26891 5 - 7 - 34033 + 6 + 24971 - 7 - 11 - 40840 + 6 + 8 + 40337 - 11 - 17 - 34033 + 8 + 12 + 32654 - 17 + 12 + 18 + 38417 + + + 18 23 - 34033 + 34575 23 40 - 36756 + 36496 40 - 707 - 34033 + 76 + 34575 - 1013 - 1414 - 4084 + 83 + 891 + 15366 @@ -8439,52 +8505,57 @@ 1 2 - 107545 + 96042 2 3 - 54453 + 46100 3 4 - 35394 + 34575 4 5 - 34033 + 28812 5 - 7 - 38117 + 6 + 36496 - 7 - 11 - 40840 + 6 + 9 + 40337 - 11 - 17 - 36756 + 9 + 13 + 40337 - 17 - 23 - 34033 + 13 + 18 + 26891 - 23 - 40 - 35394 + 18 + 25 + 38417 - 40 - 830 - 25865 + 26 + 41 + 36496 + + + 41 + 479 + 30733 @@ -8500,52 +8571,57 @@ 1 2 - 118436 + 99884 2 3 - 63982 + 57625 3 4 - 36756 + 36496 4 5 - 34033 + 32654 5 - 7 - 35394 + 6 + 32654 - 7 - 11 - 40840 + 6 + 8 + 34575 - 11 - 17 - 34033 + 8 + 12 + 38417 - 17 - 26 - 34033 + 12 + 18 + 32654 - 26 - 56 - 34033 + 18 + 25 + 34575 - 64 + 25 + 47 + 34575 + + + 51 138 - 10890 + 21129 @@ -8561,17 +8637,17 @@ 1 2 - 4040456 + 4694572 2 11 - 341696 + 407221 11 - 1358 - 123881 + 426 + 151747 @@ -8587,17 +8663,17 @@ 1 2 - 4040456 + 4694572 2 6 - 359393 + 426430 6 - 783 - 106184 + 224 + 132539 @@ -8613,7 +8689,7 @@ 1 2 - 4506034 + 5253541 @@ -8623,26 +8699,26 @@ file_class - 14974 + 17287 id - 14974 + 17287 class_object - 122520 + 163272 id - 122520 + 163272 instance - 122520 + 163272 @@ -8656,7 +8732,7 @@ 1 2 - 122520 + 163272 @@ -8672,7 +8748,7 @@ 1 2 - 122520 + 163272 @@ -8682,19 +8758,19 @@ type_companion_object - 217814 + 307336 id - 217814 + 307336 instance - 217814 + 307336 companion_object - 217814 + 307336 @@ -8708,7 +8784,7 @@ 1 2 - 217814 + 307336 @@ -8724,7 +8800,7 @@ 1 2 - 217814 + 307336 @@ -8740,7 +8816,7 @@ 1 2 - 217814 + 307336 @@ -8756,7 +8832,7 @@ 1 2 - 217814 + 307336 @@ -8772,7 +8848,7 @@ 1 2 - 217814 + 307336 @@ -8788,7 +8864,7 @@ 1 2 - 217814 + 307336 @@ -8798,15 +8874,15 @@ kt_nullable_types - 1361 + 1920 id - 1361 + 1920 classid - 1361 + 1920 @@ -8820,7 +8896,7 @@ 1 2 - 1361 + 1920 @@ -8836,7 +8912,7 @@ 1 2 - 1361 + 1920 @@ -8846,15 +8922,15 @@ kt_notnull_types - 191419 + 172391 id - 191419 + 172391 classid - 191419 + 172391 @@ -8868,7 +8944,7 @@ 1 2 - 191419 + 172391 @@ -8884,7 +8960,7 @@ 1 2 - 191419 + 172391 @@ -8894,19 +8970,19 @@ kt_type_alias - 2060 + 1821 id - 2060 + 1821 name - 2060 + 1821 kttypeid - 1030 + 910 @@ -8920,7 +8996,7 @@ 1 2 - 2060 + 1821 @@ -8936,7 +9012,7 @@ 1 2 - 2060 + 1821 @@ -8952,7 +9028,7 @@ 1 2 - 2060 + 1821 @@ -8968,7 +9044,7 @@ 1 2 - 2060 + 1821 @@ -8984,7 +9060,7 @@ 2 3 - 1030 + 910 @@ -9000,7 +9076,7 @@ 2 3 - 1030 + 910 @@ -9021,23 +9097,23 @@ interfaces - 21501109 + 23200100 id - 21501109 + 23200100 nodeName - 5448969 + 8705320 parentid - 350 + 430271 sourceid - 2074 + 2787162 @@ -9051,7 +9127,7 @@ 1 2 - 21501109 + 23200100 @@ -9067,7 +9143,7 @@ 1 2 - 21501109 + 23200100 @@ -9083,7 +9159,7 @@ 1 2 - 21501109 + 23200100 @@ -9099,27 +9175,22 @@ 1 2 - 3495545 + 6834406 2 3 - 811460 + 1079521 3 - 5 - 410487 + 25 + 655011 - 5 - 12 - 426139 - - - 12 - 9655 - 305336 + 25 + 345 + 136380 @@ -9135,231 +9206,221 @@ 1 2 - 5448745 + 7996524 2 - 3 - 224 - - - - - - - nodeName - sourceid - - - 12 - - - 1 - 2 - 5448653 - - - 2 - 6 - 316 - - - - - - - parentid - id - - - 12 - - - 1 - 2 - 57 - - - 2 - 3 - 34 - - - 3 4 - 28 + 695349 4 - 6 - 28 - - - 6 - 9 - 28 - - - 10 - 16 - 28 - - - 16 - 20 - 28 - - - 21 - 212 - 28 - - - 288 - 1113 - 28 - - - 1315 - 27761 - 28 - - - 36093 - 2073873 - 28 - - - - - - - parentid - nodeName - - - 12 - - - 1 - 2 - 57 - - - 2 - 3 - 34 - - - 3 - 4 - 28 - - - 4 - 5 - 5 - - - 5 - 6 - 28 - - - 6 - 11 - 28 - - - 11 - 14 - 28 - - - 15 - 20 - 28 - - - 21 - 107 - 28 - - - 153 - 381 - 28 - - - 3060 - 15096 - 28 - - - 36080 - 500307 - 22 - - - - - - - parentid - sourceid - - - 12 - - - 1 - 2 - 97 - - - 2 - 3 - 40 - - - 3 - 4 - 34 - - - 4 - 6 - 28 - - - 6 7 - 11 + 13445 + + + + + + + nodeName + sourceid + + + 12 + + + 1 + 2 + 7967711 - 7 + 2 + 4 + 718400 + + + 4 + 7 + 19208 + + + + + + + parentid + id + + + 12 + + + 1 + 2 + 113330 + + + 2 + 3 + 55704 + + + 3 + 4 + 48021 + + + 4 + 5 + 26891 + + + 5 8 - 40 + 36496 8 + 13 + 34575 + + + 13 + 18 + 34575 + + + 18 + 41 + 32654 + + + 42 + 182 + 32654 + + + 187 + 4152 + 15366 + + + + + + + parentid + nodeName + + + 12 + + + 1 + 2 + 113330 + + + 2 + 3 + 55704 + + + 3 + 4 + 48021 + + + 4 + 5 + 38417 + + + 5 + 7 + 24971 + + + 7 10 - 22 + 32654 10 - 11 - 28 - - - 11 15 - 28 + 36496 - 19 - 40 - 17 + 15 + 28 + 32654 + + + 30 + 94 + 32654 + + + 100 + 1213 + 15366 + + + + + + + parentid + sourceid + + + 12 + + + 1 + 2 + 140222 + + + 2 + 3 + 65309 + + + 3 + 4 + 44179 + + + 4 + 5 + 34575 + + + 5 + 7 + 28812 + + + 7 + 9 + 34575 + + + 9 + 14 + 34575 + + + 14 + 26 + 32654 + + + 26 + 160 + 15366 @@ -9375,32 +9436,17 @@ 1 2 - 1292 + 2391465 2 - 7 - 166 + 11 + 213215 - 7 - 53 - 160 - - - 55 - 289 - 166 - - - 353 - 3260 - 160 - - - 3665 - 450913 - 126 + 11 + 1565 + 182481 @@ -9416,32 +9462,17 @@ 1 2 - 1292 + 2391465 2 6 - 172 + 217056 6 - 31 - 160 - - - 31 - 110 - 160 - - - 115 - 1202 - 160 - - - 1336 - 101026 - 126 + 492 + 178639 @@ -9457,7 +9488,7 @@ 1 2 - 2074 + 2787162 @@ -9467,15 +9498,15 @@ fielddecls - 398872 + 199475 id - 398872 + 199475 parentid - 59898 + 25503 @@ -9489,7 +9520,7 @@ 1 2 - 398872 + 199475 @@ -9505,32 +9536,57 @@ 1 2 - 29949 + 4554 2 3 - 13613 + 5465 3 4 - 5445 + 1821 4 - 5 - 2722 + 6 + 1821 6 - 16 - 5445 + 7 + 2732 - 40 - 159 - 2722 + 7 + 9 + 1821 + + + 9 + 10 + 910 + + + 10 + 11 + 1821 + + + 13 + 18 + 1821 + + + 19 + 20 + 1821 + + + 57 + 58 + 910 @@ -9540,19 +9596,19 @@ fieldDeclaredIn - 398872 + 199475 fieldId - 398872 + 199475 fieldDeclId - 398872 + 199475 pos - 1361 + 910 @@ -9566,7 +9622,7 @@ 1 2 - 398872 + 199475 @@ -9582,7 +9638,7 @@ 1 2 - 398872 + 199475 @@ -9598,7 +9654,7 @@ 1 2 - 398872 + 199475 @@ -9614,7 +9670,7 @@ 1 2 - 398872 + 199475 @@ -9628,9 +9684,9 @@ 12 - 293 - 294 - 1361 + 219 + 220 + 910 @@ -9644,9 +9700,9 @@ 12 - 293 - 294 - 1361 + 219 + 220 + 910 @@ -9656,27 +9712,27 @@ fields - 27509955 + 19350704 id - 27509955 + 19350704 nodeName - 10900247 + 13628474 typeid - 2728125 + 3038794 parentid - 3851230 + 4089502 sourceid - 27509955 + 19350704 @@ -9690,7 +9746,7 @@ 1 2 - 27509955 + 19350704 @@ -9706,7 +9762,7 @@ 1 2 - 27509955 + 19350704 @@ -9722,7 +9778,7 @@ 1 2 - 27509955 + 19350704 @@ -9738,7 +9794,7 @@ 1 2 - 27509955 + 19350704 @@ -9754,22 +9810,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9785,17 +9836,17 @@ 1 2 - 9875159 + 12416414 2 - 4 - 850837 + 5 + 1085283 - 4 + 5 160 - 174251 + 126776 @@ -9811,22 +9862,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9842,22 +9888,17 @@ 1 2 - 8061854 + 12016876 2 3 - 1433490 + 1123700 3 - 11 - 760988 - - - 11 - 828 - 643913 + 722 + 487897 @@ -9873,32 +9914,27 @@ 1 2 - 1732985 + 2059157 2 3 - 338973 + 320782 3 4 - 175612 + 213215 4 - 7 - 208284 + 8 + 245869 - 7 - 24 - 205562 - - - 24 - 7479 - 66705 + 8 + 2588 + 199769 @@ -9914,27 +9950,27 @@ 1 2 - 1894985 + 2120625 2 3 - 302217 + 299653 3 4 - 183780 + 199769 4 9 - 212369 + 255473 9 - 2335 - 134772 + 2016 + 163272 @@ -9950,17 +9986,17 @@ 1 2 - 2326529 + 2706486 2 4 - 228705 + 251632 4 - 1392 - 172890 + 1014 + 80675 @@ -9976,32 +10012,27 @@ 1 2 - 1732985 + 2059157 2 3 - 338973 + 320782 3 4 - 175612 + 213215 4 - 7 - 208284 + 8 + 245869 - 7 - 24 - 205562 - - - 24 - 7479 - 66705 + 8 + 2588 + 199769 @@ -10017,37 +10048,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10063,37 +10089,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10109,27 +10130,22 @@ 1 2 - 2499419 + 3031110 2 3 - 623493 + 595465 3 - 4 - 243679 + 5 + 347674 - 4 - 7 - 338973 - - - 7 + 5 76 - 145663 + 115251 @@ -10145,37 +10161,32 @@ 1 2 - 1937186 + 2427962 2 3 - 484636 + 478293 3 4 - 303578 + 303495 4 6 - 341696 + 338070 6 - 10 - 300856 + 13 + 330387 - 10 - 27 - 291326 - - - 27 + 13 1610 - 191948 + 211294 @@ -10191,7 +10202,7 @@ 1 2 - 27509955 + 19350704 @@ -10207,7 +10218,7 @@ 1 2 - 27509955 + 19350704 @@ -10223,7 +10234,7 @@ 1 2 - 27509955 + 19350704 @@ -10239,7 +10250,7 @@ 1 2 - 27509955 + 19350704 @@ -10249,15 +10260,15 @@ fieldsKotlinType - 27509955 + 19350704 id - 27509955 + 19350704 kttypeid - 1361 + 1920 @@ -10271,7 +10282,7 @@ 1 2 - 27509955 + 19350704 @@ -10285,9 +10296,9 @@ 12 - 20208 - 20209 - 1361 + 10074 + 10075 + 1920 @@ -10297,31 +10308,31 @@ constrs - 6869320 + 8006128 id - 6869320 + 8006128 nodeName - 3746407 + 4333451 signature - 5871458 + 6803672 typeid - 2722 + 3841 parentid - 4835479 + 5639633 sourceid - 5054654 + 5720309 @@ -10335,7 +10346,7 @@ 1 2 - 6869320 + 8006128 @@ -10351,7 +10362,7 @@ 1 2 - 6869320 + 8006128 @@ -10367,7 +10378,7 @@ 1 2 - 6869320 + 8006128 @@ -10383,7 +10394,7 @@ 1 2 - 6869320 + 8006128 @@ -10399,7 +10410,7 @@ 1 2 - 6869320 + 8006128 @@ -10415,22 +10426,58 @@ 1 2 - 2361924 + 2623889 2 3 - 835862 + 1085283 + + + 3 + 4 + 259315 + + + 4 + 11 + 326545 + + + 11 + 36 + 38417 + + + + + + + nodeName + signature + + + 12 + + + 1 + 2 + 2977327 + + + 2 + 3 + 868226 3 5 - 345780 + 341912 5 - 42 - 202839 + 19 + 145985 @@ -10438,7 +10485,7 @@ nodeName - signature + typeid 12 @@ -10446,95 +10493,64 @@ 1 2 - 2628747 + 4333451 + + + + + + + nodeName + parentid + + + 12 + + + 1 + 2 + 3764878 2 3 - 683392 + 401458 + + + 3 + 36 + 167114 + + + + + + + nodeName + sourceid + + + 12 + + + 1 + 2 + 2737220 + + + 2 + 3 + 1083362 3 5 - 302217 + 353437 5 - 19 - 132049 - - - - - - - nodeName - typeid - - - 12 - - - 1 - 2 - 3746407 - - - - - - - nodeName - parentid - - - 12 - - - 1 - 2 - 3287635 - - - 2 - 3 - 314469 - - - 3 - 42 - 144302 - - - - - - - nodeName - sourceid - - - 12 - - - 1 - 2 - 2453134 - - - 2 - 3 - 827694 - - - 3 - 5 - 318553 - - - 5 - 38 - 147024 + 32 + 159431 @@ -10550,12 +10566,12 @@ 1 2 - 5461695 + 6302329 2 - 42 - 409763 + 36 + 501343 @@ -10571,7 +10587,7 @@ 1 2 - 5871458 + 6803672 @@ -10587,7 +10603,7 @@ 1 2 - 5871458 + 6803672 @@ -10603,12 +10619,12 @@ 1 2 - 5461695 + 6302329 2 - 42 - 409763 + 36 + 501343 @@ -10624,12 +10640,12 @@ 1 2 - 5591022 + 6461760 2 - 32 - 280436 + 23 + 341912 @@ -10643,14 +10659,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 5015 - 5016 - 1361 + 4146 + 4147 + 1920 @@ -10666,12 +10682,12 @@ 1 2 - 1361 + 1920 - 2751 - 2752 - 1361 + 2255 + 2256 + 1920 @@ -10687,12 +10703,12 @@ 1 2 - 1361 + 1920 - 4312 - 4313 - 1361 + 3541 + 3542 + 1920 @@ -10706,14 +10722,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 3521 - 3522 - 1361 + 2914 + 2915 + 1920 @@ -10727,14 +10743,14 @@ 12 - 31 - 32 - 1361 + 22 + 23 + 1920 - 3682 - 3683 - 1361 + 2956 + 2957 + 1920 @@ -10750,22 +10766,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10781,7 +10797,7 @@ 1 2 - 4835479 + 5639633 @@ -10797,22 +10813,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10828,7 +10844,7 @@ 1 2 - 4835479 + 5639633 @@ -10844,22 +10860,22 @@ 1 2 - 3676978 + 4256617 2 3 - 737846 + 895118 3 6 - 366200 + 434113 6 19 - 54453 + 53783 @@ -10875,12 +10891,12 @@ 1 2 - 4742907 + 5357267 2 - 259 - 311746 + 209 + 363041 @@ -10896,12 +10912,12 @@ 1 2 - 4742907 + 5357267 2 - 212 - 311746 + 172 + 363041 @@ -10917,12 +10933,12 @@ 1 2 - 4742907 + 5357267 2 - 212 - 311746 + 172 + 363041 @@ -10938,7 +10954,7 @@ 1 2 - 5054654 + 5720309 @@ -10954,12 +10970,12 @@ 1 2 - 4742907 + 5357267 2 - 259 - 311746 + 209 + 363041 @@ -10969,15 +10985,15 @@ constrsKotlinType - 6869320 + 8006128 id - 6869320 + 8006128 kttypeid - 1361 + 1920 @@ -10991,7 +11007,7 @@ 1 2 - 6869320 + 8006128 @@ -11005,9 +11021,9 @@ 12 - 5046 - 5047 - 1361 + 4168 + 4169 + 1920 @@ -11017,31 +11033,31 @@ methods - 93308954 + 109719302 id - 93308954 + 109719302 nodeName - 20326164 + 22908130 signature - 29772501 + 33369112 typeid - 11583640 + 13338425 parentid - 11270532 + 12810189 sourceid - 58543057 + 67091663 @@ -11055,7 +11071,7 @@ 1 2 - 93308954 + 109719302 @@ -11071,7 +11087,7 @@ 1 2 - 93308954 + 109719302 @@ -11087,7 +11103,7 @@ 1 2 - 93308954 + 109719302 @@ -11103,7 +11119,7 @@ 1 2 - 93308954 + 109719302 @@ -11119,7 +11135,7 @@ 1 2 - 93308954 + 109719302 @@ -11135,32 +11151,32 @@ 1 2 - 11834127 + 13324979 2 3 - 3821280 + 4070294 3 4 - 1315054 + 1573181 4 7 - 1792884 + 2026503 7 - 271 - 1524700 + 56 + 1719166 - 276 - 2134 - 38117 + 57 + 1769 + 194006 @@ -11176,17 +11192,17 @@ 1 2 - 16853387 + 19150935 2 3 - 2115522 + 2228193 3 - 361 - 1357255 + 298 + 1529001 @@ -11202,22 +11218,22 @@ 1 2 - 17082092 + 19179748 2 3 - 1678532 + 1872834 3 - 52 - 1524700 + 25 + 1726849 - 52 - 845 - 40840 + 25 + 741 + 128697 @@ -11233,27 +11249,27 @@ 1 2 - 12555637 + 14028012 2 3 - 3596659 + 3889733 3 4 - 1245625 + 1502109 4 7 - 1577792 + 1817129 7 - 1278 - 1350449 + 1099 + 1671144 @@ -11269,27 +11285,27 @@ 1 2 - 12213940 + 13743725 2 3 - 3951969 + 4283509 3 4 - 1297356 + 1544368 4 7 - 1656750 + 1857467 7 - 928 - 1206147 + 800 + 1479059 @@ -11305,22 +11321,27 @@ 1 2 - 20356114 + 22735253 2 3 - 4957999 + 5434102 3 5 - 2363285 + 2635414 5 - 1275 - 2095101 + 157 + 2502875 + + + 157 + 1096 + 61467 @@ -11336,7 +11357,7 @@ 1 2 - 29772501 + 33369112 @@ -11352,17 +11373,17 @@ 1 2 - 26733991 + 29957672 2 5 - 2383706 + 2650781 5 - 843 - 654804 + 739 + 760659 @@ -11378,22 +11399,27 @@ 1 2 - 20360198 + 22741015 2 3 - 4956638 + 5432181 3 5 - 2361924 + 2631572 5 - 1275 - 2093740 + 157 + 2502875 + + + 157 + 1096 + 61467 @@ -11409,22 +11435,22 @@ 1 2 - 20978246 + 23365294 2 3 - 5076436 + 5656921 3 6 - 2533453 + 2900492 6 - 923 - 1184365 + 795 + 1446404 @@ -11440,32 +11466,32 @@ 1 2 - 5684955 + 6603903 2 3 - 2449050 + 2729536 3 4 - 1089071 + 1208218 4 6 - 925711 + 1119859 6 - 14 - 875341 + 15 + 1019974 - 14 - 11667 - 559510 + 15 + 10335 + 656932 @@ -11481,22 +11507,22 @@ 1 2 - 7613973 + 8714924 2 3 - 2218983 + 2620047 3 6 - 1060483 + 1167880 6 - 3940 - 690199 + 2888 + 835572 @@ -11512,27 +11538,22 @@ 1 2 - 7370293 + 8565097 2 3 - 2274798 + 2602760 3 - 5 - 875341 + 6 + 1210139 - 5 - 17 - 882148 - - - 17 - 5689 - 181058 + 6 + 4142 + 960428 @@ -11548,27 +11569,27 @@ 1 2 - 6786279 + 7714158 2 3 - 2466747 + 2869759 3 4 - 1003307 + 1108333 4 - 9 - 916181 + 8 + 1069916 - 9 - 3420 - 411124 + 8 + 2865 + 576256 @@ -11584,32 +11605,32 @@ 1 2 - 6180482 + 7166714 2 3 - 2262546 + 2524004 3 4 - 985610 + 1096808 4 6 - 910736 + 1094888 6 16 - 890316 + 1016132 16 - 8855 - 353948 + 6435 + 439876 @@ -11625,52 +11646,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11686,52 +11707,52 @@ 1 2 - 3244072 + 3678439 2 3 - 1308247 + 1457929 3 4 - 1109491 + 1231268 4 5 - 785493 + 791392 5 7 - 887593 + 960428 7 10 - 1015559 + 1183247 10 13 - 942047 + 1102571 13 - 17 - 875341 + 18 + 849018 - 17 - 35 - 848114 + 18 + 26 + 968111 - 35 + 26 290 - 254570 + 587781 @@ -11747,52 +11768,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11808,47 +11829,52 @@ 1 2 - 3887986 + 4348818 2 3 - 1615910 + 1757583 3 4 - 1327306 + 1436800 4 5 - 786854 + 922010 5 6 - 637107 + 743371 6 7 - 498250 + 564731 7 - 9 - 1033256 + 8 + 879752 - 9 - 13 - 882148 + 8 + 11 + 1160197 - 13 + 11 + 31 + 964269 + + + 33 78 - 601712 + 32654 @@ -11864,52 +11890,52 @@ 1 2 - 3190980 + 3630418 2 3 - 1287827 + 1456008 3 4 - 1029172 + 1164038 4 5 - 744652 + 735687 5 7 - 924349 + 1021895 7 10 - 952937 + 1106413 10 13 - 997862 + 1146751 13 - 19 - 908013 + 21 + 1181326 - 19 - 38 - 909375 + 21 + 40 + 1021895 - 38 + 40 319 - 325360 + 345754 @@ -11925,12 +11951,17 @@ 1 2 - 54190854 + 61836200 2 - 349 - 4352203 + 50 + 5032643 + + + 52 + 286 + 222819 @@ -11946,7 +11977,7 @@ 1 2 - 58543057 + 67091663 @@ -11962,12 +11993,12 @@ 1 2 - 58259899 + 66767038 2 - 347 - 283158 + 284 + 324624 @@ -11983,12 +12014,12 @@ 1 2 - 56848189 + 65030584 2 - 259 - 1694868 + 209 + 2061078 @@ -12004,12 +12035,17 @@ 1 2 - 54190854 + 61836200 2 - 349 - 4352203 + 50 + 5032643 + + + 52 + 286 + 222819 @@ -12019,15 +12055,15 @@ methodsKotlinType - 93308954 + 109719302 id - 93308954 + 109719302 kttypeid - 1361 + 1920 @@ -12041,7 +12077,7 @@ 1 2 - 93308954 + 109719302 @@ -12055,9 +12091,9 @@ 12 - 68542 - 68543 - 1361 + 57120 + 57121 + 1920 @@ -12067,27 +12103,27 @@ params - 101015498 + 120852585 id - 101015498 + 120852585 typeid - 11171154 + 12833239 pos - 29949 + 42258 parentid - 56251922 + 65007534 sourceid - 61310661 + 73639861 @@ -12101,7 +12137,7 @@ 1 2 - 101015498 + 120852585 @@ -12117,7 +12153,7 @@ 1 2 - 101015498 + 120852585 @@ -12133,7 +12169,7 @@ 1 2 - 101015498 + 120852585 @@ -12149,7 +12185,7 @@ 1 2 - 101015498 + 120852585 @@ -12165,32 +12201,37 @@ 1 2 - 5943609 + 6763334 2 3 - 1712565 + 1945827 3 4 - 869896 + 948902 4 6 - 970635 + 1148671 6 12 - 867173 + 1018053 12 - 7469 - 807274 + 326 + 966190 + + + 343 + 6738 + 42258 @@ -12206,17 +12247,22 @@ 1 2 - 9232606 + 10436011 2 3 - 1157138 + 1342678 3 + 8 + 964269 + + + 8 17 - 781409 + 90280 @@ -12232,32 +12278,32 @@ 1 2 - 6134197 + 7005362 2 3 - 1677170 + 1895885 3 4 - 888954 + 975794 4 6 - 917543 + 1087204 6 13 - 867173 + 1008449 13 - 5265 - 686115 + 4326 + 860543 @@ -12273,32 +12319,32 @@ 1 2 - 6337036 + 7216656 2 3 - 1569624 + 1788317 3 4 - 901206 + 996924 4 6 - 947492 + 1117938 6 13 - 856282 + 1002686 13 - 6292 - 559510 + 5757 + 710716 @@ -12314,57 +12360,57 @@ 1 2 - 2722 + 3841 - 53 - 56 - 2722 + 50 + 53 + 3841 - 110 - 112 - 2722 + 104 + 106 + 3841 - 165 - 172 - 2722 + 157 + 165 + 3841 - 224 - 242 - 2722 + 214 + 231 + 3841 - 305 - 330 - 2722 + 291 + 315 + 3841 - 524 - 666 - 2722 + 485 + 606 + 3841 - 880 - 1142 - 2722 + 804 + 1067 + 3841 - 1517 - 2090 - 2722 + 1445 + 2015 + 3841 - 3299 - 5949 - 2722 + 3084 + 5199 + 3841 - 15053 - 41322 - 2722 + 12689 + 33844 + 3841 @@ -12380,57 +12426,57 @@ 1 2 - 2722 + 3841 2 5 - 2722 + 3841 6 7 - 2722 + 3841 - 10 - 12 - 2722 + 11 + 14 + 3841 - 13 - 19 - 2722 + 15 + 20 + 3841 - 26 - 38 - 2722 + 27 + 37 + 3841 57 - 76 - 2722 + 75 + 3841 - 99 - 159 - 2722 + 97 + 153 + 3841 - 212 - 306 - 2722 + 201 + 289 + 3841 - 452 - 889 - 2722 + 403 + 777 + 3841 - 2370 - 6264 - 2722 + 1979 + 5089 + 3841 @@ -12446,57 +12492,57 @@ 1 2 - 2722 + 3841 - 53 - 56 - 2722 + 50 + 53 + 3841 - 110 - 112 - 2722 + 104 + 106 + 3841 - 165 - 172 - 2722 + 157 + 165 + 3841 - 224 - 242 - 2722 + 214 + 231 + 3841 - 305 - 330 - 2722 + 291 + 315 + 3841 - 524 - 666 - 2722 + 485 + 606 + 3841 - 880 - 1142 - 2722 + 804 + 1067 + 3841 - 1517 - 2090 - 2722 + 1445 + 2015 + 3841 - 3299 - 5949 - 2722 + 3084 + 5199 + 3841 - 15053 - 41322 - 2722 + 12689 + 33844 + 3841 @@ -12512,57 +12558,57 @@ 1 2 - 2722 + 3841 2 5 - 2722 + 3841 6 8 - 2722 + 3841 - 10 - 13 - 2722 + 11 + 15 + 3841 - 14 - 28 - 2722 + 16 + 29 + 3841 - 38 + 39 63 - 2722 + 3841 - 98 - 138 - 2722 + 101 + 144 + 3841 - 193 - 344 - 2722 + 210 + 386 + 3841 - 556 - 966 - 2722 + 628 + 1069 + 3841 - 1954 - 4172 - 2722 + 1955 + 3748 + 3841 - 10056 - 26381 - 2722 + 8555 + 21355 + 3841 @@ -12578,27 +12624,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12614,17 +12660,17 @@ 1 2 - 39751122 + 45326442 2 3 - 12655015 + 14805959 3 23 - 3845785 + 4875132 @@ -12640,27 +12686,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12676,27 +12722,27 @@ 1 2 - 35759674 + 40633790 2 3 - 12394999 + 14389133 3 4 - 3606189 + 4060689 4 - 15 - 4258270 + 10 + 4992305 - 15 + 10 23 - 232789 + 931615 @@ -12712,12 +12758,12 @@ 1 2 - 56891752 + 68584168 2 - 349 - 4418909 + 286 + 5055693 @@ -12733,12 +12779,12 @@ 1 2 - 59772347 + 71932220 2 - 349 - 1538314 + 286 + 1707641 @@ -12754,7 +12800,7 @@ 1 2 - 61310661 + 73639861 @@ -12770,12 +12816,12 @@ 1 2 - 56891752 + 68584168 2 - 349 - 4418909 + 286 + 5055693 @@ -12785,15 +12831,15 @@ paramsKotlinType - 101015498 + 120852585 id - 101015498 + 120852585 kttypeid - 1361 + 1920 @@ -12807,7 +12853,7 @@ 1 2 - 101015498 + 120852585 @@ -12821,9 +12867,9 @@ 12 - 74203 - 74204 - 1361 + 62916 + 62917 + 1920 @@ -12833,15 +12879,15 @@ paramName - 10331207 + 15639610 id - 10331207 + 15639610 nodeName - 1662195 + 2335761 @@ -12855,7 +12901,7 @@ 1 2 - 10331207 + 15639610 @@ -12871,37 +12917,37 @@ 1 2 - 717426 + 998845 2 3 - 328082 + 451401 3 4 - 174251 + 249711 4 5 - 129327 + 170956 5 - 9 - 137495 + 8 + 182481 - 9 - 25 - 130688 + 8 + 18 + 176718 - 25 - 517 - 44924 + 18 + 769 + 105647 @@ -12911,30 +12957,30 @@ isVarargsParam - 1003307 + 945061 param - 1003307 + 945061 exceptions - 1228169 + 1232644 id - 1228169 + 1232644 typeid - 36993 + 36990 parentid - 982877 + 987367 @@ -12948,7 +12994,7 @@ 1 2 - 1228169 + 1232644 @@ -12964,7 +13010,7 @@ 1 2 - 1228169 + 1232644 @@ -12980,7 +13026,7 @@ 1 2 - 11951 + 11950 2 @@ -13010,17 +13056,17 @@ 20 35 - 3414 - - - 49 - 107 2845 - 187 + 41 + 93 + 2845 + + + 106 813 - 1707 + 2276 @@ -13036,7 +13082,7 @@ 1 2 - 11951 + 11950 2 @@ -13066,17 +13112,17 @@ 20 35 - 3414 - - - 49 - 107 2845 - 187 + 41 + 93 + 2845 + + + 106 813 - 1707 + 2276 @@ -13092,12 +13138,12 @@ 1 2 - 750674 + 755179 2 3 - 224234 + 224220 3 @@ -13118,12 +13164,12 @@ 1 2 - 750674 + 755179 2 3 - 224234 + 224220 3 @@ -13138,41 +13184,41 @@ isAnnotType - 30058 + 29260 interfaceid - 30058 + 29260 isAnnotElem - 61062 + 61065 methodid - 61062 + 61065 annotValue - 1574849 + 1574925 parentid - 568147 + 568174 id2 - 52102 + 52104 value - 1574849 + 1574925 @@ -13186,32 +13232,32 @@ 1 2 - 153486 + 153493 2 3 - 252712 + 252724 3 4 - 48949 + 48951 4 6 - 26548 + 26550 6 7 - 35177 + 35179 7 9 - 46626 + 46628 9 @@ -13232,37 +13278,37 @@ 1 2 - 138054 + 138061 2 3 - 268144 + 268157 3 4 - 47290 + 47292 4 6 - 26051 + 26052 6 8 - 39657 + 39659 8 10 - 44137 + 44139 10 13 - 4811 + 4812 @@ -13278,22 +13324,22 @@ 1 2 - 17090 + 17091 2 3 - 5143 + 5144 3 4 - 2654 + 2655 4 6 - 4811 + 4812 6 @@ -13339,7 +13385,7 @@ 1 2 - 15265 + 15266 2 @@ -13364,7 +13410,7 @@ 8 10 - 4811 + 4812 10 @@ -13400,7 +13446,7 @@ 1 2 - 1574849 + 1574925 @@ -13416,7 +13462,7 @@ 1 2 - 1574849 + 1574925 @@ -13426,49 +13472,49 @@ isEnumType - 349864 + 397617 classid - 349864 + 397617 isEnumConst - 321905 + 3081053 fieldid - 321905 + 3081053 typeVars - 5105024 + 6288883 id - 5105024 + 6288883 nodeName - 70789 + 86438 pos - 5445 + 7683 kind - 1361 + 1920 parentid - 3715096 + 4444861 @@ -13482,7 +13528,7 @@ 1 2 - 5105024 + 6288883 @@ -13498,7 +13544,7 @@ 1 2 - 5105024 + 6288883 @@ -13514,7 +13560,7 @@ 1 2 - 5105024 + 6288883 @@ -13530,7 +13576,7 @@ 1 2 - 5105024 + 6288883 @@ -13546,47 +13592,47 @@ 1 2 - 20420 + 21129 2 3 - 10890 + 11525 3 4 - 6806 + 9604 4 7 - 5445 + 7683 7 10 - 5445 + 7683 10 28 - 5445 + 7683 - 37 - 71 - 5445 + 36 + 69 + 7683 71 - 253 - 5445 + 412 + 7683 - 459 - 951 - 5445 + 603 + 710 + 5762 @@ -13602,22 +13648,22 @@ 1 2 - 44924 + 51863 2 3 - 16336 + 23050 3 4 - 8168 + 9604 4 5 - 1361 + 1920 @@ -13633,7 +13679,7 @@ 1 2 - 70789 + 86438 @@ -13649,47 +13695,47 @@ 1 2 - 20420 + 21129 2 3 - 10890 + 11525 3 4 - 6806 + 9604 4 7 - 5445 + 7683 7 10 - 5445 + 7683 10 28 - 5445 + 7683 - 37 - 71 - 5445 + 36 + 69 + 7683 71 - 253 - 5445 + 412 + 7683 - 459 - 951 - 5445 + 603 + 710 + 5762 @@ -13705,22 +13751,22 @@ 6 7 - 1361 + 1920 - 94 - 95 - 1361 + 89 + 90 + 1920 - 921 - 922 - 1361 + 865 + 866 + 1920 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13736,22 +13782,22 @@ 2 3 - 1361 + 1920 13 14 - 1361 + 1920 - 23 - 24 - 1361 + 21 + 22 + 1920 - 41 - 42 - 1361 + 34 + 35 + 1920 @@ -13767,7 +13813,7 @@ 1 2 - 5445 + 7683 @@ -13783,22 +13829,22 @@ 6 7 - 1361 + 1920 - 94 - 95 - 1361 + 89 + 90 + 1920 - 921 - 922 - 1361 + 865 + 866 + 1920 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13812,9 +13858,9 @@ 12 - 3750 - 3751 - 1361 + 3274 + 3275 + 1920 @@ -13828,9 +13874,9 @@ 12 - 52 - 53 - 1361 + 45 + 46 + 1920 @@ -13846,7 +13892,7 @@ 4 5 - 1361 + 1920 @@ -13860,9 +13906,9 @@ 12 - 2729 - 2730 - 1361 + 2314 + 2315 + 1920 @@ -13878,17 +13924,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13904,17 +13950,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13930,17 +13976,17 @@ 1 2 - 2461302 + 2783320 2 3 - 1125828 + 1490584 3 5 - 127965 + 170956 @@ -13956,7 +14002,7 @@ 1 2 - 3715096 + 4444861 @@ -13966,19 +14012,19 @@ wildcards - 3629331 + 3338447 id - 3629331 + 3338447 nodeName - 980164 + 533998 kind - 2722 + 3841 @@ -13992,7 +14038,7 @@ 1 2 - 3629331 + 3338447 @@ -14008,7 +14054,7 @@ 1 2 - 3629331 + 3338447 @@ -14024,17 +14070,22 @@ 1 2 - 789577 + 397617 2 3 - 119797 + 55704 3 - 214 - 70789 + 7 + 44179 + + + 7 + 170 + 36496 @@ -14050,7 +14101,7 @@ 1 2 - 980164 + 533998 @@ -14064,14 +14115,14 @@ 12 - 1027 - 1028 - 1361 + 791 + 792 + 1920 - 1639 - 1640 - 1361 + 947 + 948 + 1920 @@ -14085,14 +14136,14 @@ 12 - 222 - 223 - 1361 + 91 + 92 + 1920 - 498 - 499 - 1361 + 187 + 188 + 1920 @@ -14102,23 +14153,23 @@ typeBounds - 4383514 + 4229725 id - 4383514 + 4229725 typeid - 3184173 + 2852471 pos - 1361 + 1920 parentid - 4383514 + 4229725 @@ -14132,7 +14183,7 @@ 1 2 - 4383514 + 4229725 @@ -14148,7 +14199,7 @@ 1 2 - 4383514 + 4229725 @@ -14164,7 +14215,7 @@ 1 2 - 4383514 + 4229725 @@ -14180,17 +14231,17 @@ 1 2 - 2506226 + 2091812 2 3 - 601712 + 695349 3 52 - 76235 + 65309 @@ -14206,7 +14257,7 @@ 1 2 - 3184173 + 2852471 @@ -14222,17 +14273,17 @@ 1 2 - 2506226 + 2091812 2 3 - 601712 + 695349 3 52 - 76235 + 65309 @@ -14246,9 +14297,9 @@ 12 - 3220 - 3221 - 1361 + 2202 + 2203 + 1920 @@ -14262,9 +14313,9 @@ 12 - 2339 - 2340 - 1361 + 1485 + 1486 + 1920 @@ -14278,9 +14329,9 @@ 12 - 3220 - 3221 - 1361 + 2202 + 2203 + 1920 @@ -14296,7 +14347,7 @@ 1 2 - 4383514 + 4229725 @@ -14312,7 +14363,7 @@ 1 2 - 4383514 + 4229725 @@ -14328,7 +14379,7 @@ 1 2 - 4383514 + 4229725 @@ -14338,11 +14389,11 @@ typeArgs - 53913162 + 53854237 argumentid - 1429292 + 1430551 pos @@ -14350,7 +14401,7 @@ parentid - 22268245 + 22244248 @@ -14364,17 +14415,17 @@ 1 2 - 866127 + 865848 2 3 - 469332 + 470615 3 11 - 93832 + 94087 @@ -14390,57 +14441,57 @@ 1 2 - 62430 + 64071 2 3 - 435425 + 433698 3 5 - 100353 + 100595 5 6 - 35320 + 35547 6 7 - 201035 + 201249 7 11 - 37958 + 39437 11 12 - 218221 + 218178 12 15 - 111144 + 111421 15 29 - 108553 + 108138 29 - 324 - 107243 + 341 + 107450 - 324 - 762773 - 11606 + 341 + 757580 + 10762 @@ -14459,48 +14510,48 @@ 5 - 598 - 599 + 597 + 598 5 - 889 - 890 + 887 + 888 5 - 1132 - 1133 + 1129 + 1130 5 - 1762 - 1763 + 1758 + 1759 5 - 3890 - 3891 + 3885 + 3886 5 - 4033 - 4034 + 4027 + 4028 5 - 51900 - 51901 + 51686 + 51687 5 - 143023 - 143024 + 142042 + 142043 5 - 161995 - 161996 + 161580 + 161581 5 @@ -14525,43 +14576,43 @@ 5 - 3896 - 3897 + 3895 + 3896 5 - 8697 - 8698 + 8694 + 8695 5 - 19018 - 19019 + 19012 + 19013 5 - 85642 - 85643 + 85622 + 85623 5 - 103285 - 103286 + 103257 + 103258 5 - 1458897 - 1458898 + 1447294 + 1447295 5 - 3827033 - 3827034 + 3800219 + 3800220 5 - 3875440 - 3875441 + 3848466 + 3848467 5 @@ -14578,22 +14629,22 @@ 1 2 - 295332 + 296162 2 3 - 13673753 + 13666793 3 4 - 7771091 + 7750153 4 11 - 528068 + 531138 @@ -14609,22 +14660,22 @@ 1 2 - 278146 + 278869 2 3 - 13607289 + 13599976 3 4 - 7789335 + 7768574 4 11 - 593474 + 596828 @@ -14634,37 +14685,37 @@ isParameterized - 25111274 + 27045654 memberid - 25111274 + 27045654 isRaw - 641191 + 731846 memberid - 641191 + 731846 erasure - 25752465 + 27777500 memberid - 25752465 + 27777500 erasureid - 865812 + 954665 @@ -14678,7 +14729,7 @@ 1 2 - 25752465 + 27777500 @@ -14694,57 +14745,62 @@ 1 2 - 144302 + 142143 2 3 - 133411 + 138301 3 4 - 88487 + 86438 4 5 - 54453 + 57625 5 6 - 50369 + 65309 6 8 - 63982 + 69150 8 - 11 - 78957 + 10 + 61467 - 11 - 19 - 70789 + 10 + 15 + 72992 - 19 - 33 - 70789 + 15 + 22 + 76834 - 33 - 93 - 65344 + 22 + 44 + 74913 - 97 - 1848 - 44924 + 46 + 124 + 72992 + + + 169 + 1564 + 36496 @@ -14754,15 +14810,15 @@ isAnonymClass - 192667 + 174213 classid - 192667 + 174213 parent - 192667 + 174213 @@ -14776,7 +14832,7 @@ 1 2 - 192667 + 174213 @@ -14792,7 +14848,7 @@ 1 2 - 192667 + 174213 @@ -14802,15 +14858,15 @@ isLocalClassOrInterface - 4057 + 3841 typeid - 4057 + 3841 parent - 4057 + 3841 @@ -14824,7 +14880,7 @@ 1 2 - 4057 + 3841 @@ -14840,7 +14896,7 @@ 1 2 - 4057 + 3841 @@ -14850,26 +14906,26 @@ isDefConstr - 139100 + 139383 constructorid - 139100 + 139383 lambdaKind - 183936 + 167982 exprId - 183936 + 167982 bodyKind - 15 + 13 @@ -14883,7 +14939,7 @@ 1 2 - 183936 + 167982 @@ -14897,9 +14953,9 @@ 12 - 11651 - 11652 - 15 + 12267 + 12268 + 13 @@ -14909,27 +14965,27 @@ arrays - 1116298 + 1375332 id - 1116298 + 1375332 nodeName - 687476 + 831730 elementtypeid - 1109491 + 1365728 dimension - 2722 + 3841 componenttypeid - 1116298 + 1375332 @@ -14943,7 +14999,7 @@ 1 2 - 1116298 + 1375332 @@ -14959,7 +15015,7 @@ 1 2 - 1116298 + 1375332 @@ -14975,7 +15031,7 @@ 1 2 - 1116298 + 1375332 @@ -14991,7 +15047,7 @@ 1 2 - 1116298 + 1375332 @@ -15007,17 +15063,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15033,17 +15089,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15059,7 +15115,7 @@ 1 2 - 687476 + 831730 @@ -15075,17 +15131,17 @@ 1 2 - 562233 + 664616 2 3 - 99377 + 140222 3 - 95 - 25865 + 87 + 26891 @@ -15101,12 +15157,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15122,12 +15178,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15143,12 +15199,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15164,12 +15220,12 @@ 1 2 - 1102685 + 1356124 2 3 - 6806 + 9604 @@ -15185,12 +15241,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15206,12 +15262,12 @@ 5 6 - 1361 + 1920 - 500 - 501 - 1361 + 428 + 429 + 1920 @@ -15227,12 +15283,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15248,12 +15304,12 @@ 5 6 - 1361 + 1920 - 815 - 816 - 1361 + 711 + 712 + 1920 @@ -15269,7 +15325,7 @@ 1 2 - 1116298 + 1375332 @@ -15285,7 +15341,7 @@ 1 2 - 1116298 + 1375332 @@ -15301,7 +15357,7 @@ 1 2 - 1116298 + 1375332 @@ -15317,7 +15373,7 @@ 1 2 - 1116298 + 1375332 @@ -15327,15 +15383,15 @@ enclInReftype - 3410156 + 4051085 child - 3410156 + 4051085 parent - 929795 + 1125621 @@ -15349,7 +15405,7 @@ 1 2 - 3410156 + 4051085 @@ -15365,32 +15421,32 @@ 1 2 - 551342 + 666537 2 3 - 148386 + 176718 3 4 - 70789 + 86438 4 - 7 - 81680 + 6 + 82596 - 7 - 51 - 70789 + 6 + 17 + 84517 - 54 - 279 - 6806 + 17 + 265 + 28812 @@ -15400,15 +15456,15 @@ extendsReftype - 47868792 + 34389087 id1 - 34023966 + 33104034 id2 - 14017716 + 13251986 @@ -15422,22 +15478,12 @@ 1 2 - 26145892 + 32118635 2 - 3 - 3141972 - - - 3 - 4 - 3633415 - - - 4 10 - 1102685 + 985399 @@ -15453,17 +15499,17 @@ 1 2 - 11930782 + 12030322 2 - 3 - 1425322 + 5 + 1023816 - 3 - 12285 - 661611 + 5 + 8715 + 197848 @@ -15473,15 +15519,15 @@ implInterface - 3048147 + 14423708 id1 - 756277 + 8255839 id2 - 2271707 + 4487119 @@ -15495,37 +15541,27 @@ 1 2 - 209615 + 4223962 2 3 - 50204 + 2829421 3 4 - 67386 + 276603 4 5 - 61962 + 920090 5 - 6 - 19294 - - - 6 7 - 305429 - - - 7 - 10 - 42384 + 5762 @@ -15541,12 +15577,17 @@ 1 2 - 2196440 + 4003064 2 - 63781 - 75267 + 4 + 366883 + + + 4 + 2275 + 117172 @@ -15556,15 +15597,15 @@ permits - 177 + 129 id1 - 43 + 31 id2 - 177 + 129 @@ -15578,17 +15619,17 @@ 1 2 - 1 + 2 2 3 - 13 + 8 3 4 - 9 + 6 4 @@ -15598,25 +15639,20 @@ 5 6 - 5 + 2 6 - 7 - 4 - - - 7 8 2 8 9 - 1 + 2 - 10 + 9 11 2 @@ -15634,7 +15670,7 @@ 1 2 - 177 + 129 @@ -15644,15 +15680,15 @@ hasModifier - 249133355 + 270713939 id1 - 166385675 + 180180147 id2 - 13613 + 26891 @@ -15666,17 +15702,17 @@ 1 2 - 84119910 + 90230296 2 3 - 81783851 + 89365911 3 4 - 481914 + 583940 @@ -15690,54 +15726,74 @@ 12 - 31 - 32 - 1361 + 4 + 5 + 1920 + + + 14 + 15 + 1920 + + + 20 + 21 + 1920 + + + 21 + 22 + 1920 34 35 - 1361 + 1920 + + + 50 + 51 + 1920 109 110 - 1361 + 1920 - 267 - 268 - 1361 + 219 + 220 + 1920 - 500 - 501 - 1361 + 3864 + 3865 + 1920 - 8143 - 8144 - 1361 + 7193 + 7194 + 1920 - 18034 - 18035 - 1361 + 9195 + 9196 + 1920 - 18282 - 18283 - 1361 + 14706 + 14707 + 1920 - 20694 - 20695 - 1361 + 18810 + 18811 + 1920 - 116912 - 116913 - 1361 + 86695 + 86696 + 1920 @@ -15747,15 +15803,15 @@ imports - 368532 + 368550 id - 368532 + 368550 holder - 58075 + 58078 name @@ -15777,7 +15833,7 @@ 1 2 - 368532 + 368550 @@ -15793,7 +15849,7 @@ 1 2 - 368532 + 368550 @@ -15809,7 +15865,7 @@ 1 2 - 368532 + 368550 @@ -15825,7 +15881,7 @@ 1 2 - 28374 + 28375 2 @@ -15871,7 +15927,7 @@ 1 2 - 54591 + 54593 2 @@ -15892,7 +15948,7 @@ 1 2 - 55089 + 55091 2 @@ -15954,7 +16010,7 @@ 1 2 - 7300 + 7301 2 @@ -16078,27 +16134,27 @@ stmts - 2530730 + 2441387 id - 2530730 + 2441387 kind - 13613 + 9674 parent - 1783355 + 1353860 idx - 216453 + 15934 bodydecl - 703812 + 367630 @@ -16112,7 +16168,7 @@ 1 2 - 2530730 + 2441387 @@ -16128,7 +16184,7 @@ 1 2 - 2530730 + 2441387 @@ -16144,7 +16200,7 @@ 1 2 - 2530730 + 2441387 @@ -16160,7 +16216,7 @@ 1 2 - 2530730 + 2441387 @@ -16169,57 +16225,6 @@ kind id - - - 12 - - - 2 - 3 - 4084 - - - 4 - 5 - 1361 - - - 72 - 73 - 1361 - - - 96 - 97 - 1361 - - - 162 - 163 - 1361 - - - 373 - 374 - 1361 - - - 525 - 526 - 1361 - - - 621 - 622 - 1361 - - - - - - - kind - parent 12 @@ -16227,88 +16232,224 @@ 1 2 - 1361 - - - 2 - 3 - 2722 - - - 4 - 5 - 1361 - - - 53 - 54 - 1361 - - - 72 - 73 - 1361 - - - 98 - 99 - 1361 - - - 233 - 234 - 1361 - - - 373 - 374 - 1361 - - - 621 - 622 - 1361 - - - - - - - kind - idx - - - 12 - - - 1 - 2 - 5445 - - - 2 - 3 - 1361 - - - 5 - 6 - 1361 + 1707 6 7 - 1361 + 569 7 8 - 2722 + 569 - 158 - 159 - 1361 + 17 + 18 + 569 + + + 20 + 21 + 569 + + + 23 + 24 + 569 + + + 33 + 34 + 569 + + + 83 + 84 + 569 + + + 91 + 92 + 569 + + + 97 + 98 + 569 + + + 265 + 266 + 569 + + + 312 + 313 + 569 + + + 560 + 561 + 569 + + + 1243 + 1244 + 569 + + + 1530 + 1531 + 569 + + + + + + + kind + parent + + + 12 + + + 1 + 2 + 2276 + + + 7 + 8 + 569 + + + 12 + 13 + 569 + + + 17 + 18 + 569 + + + 21 + 22 + 569 + + + 33 + 34 + 569 + + + 71 + 72 + 569 + + + 81 + 82 + 569 + + + 91 + 92 + 569 + + + 246 + 247 + 569 + + + 265 + 266 + 569 + + + 271 + 272 + 569 + + + 716 + 717 + 569 + + + 1192 + 1193 + 569 + + + + + + + kind + idx + + + 12 + + + 1 + 2 + 2276 + + + 3 + 4 + 569 + + + 4 + 5 + 569 + + + 6 + 7 + 1138 + + + 7 + 8 + 569 + + + 8 + 9 + 1138 + + + 10 + 11 + 1138 + + + 13 + 14 + 569 + + + 17 + 18 + 569 + + + 21 + 22 + 569 + + + 26 + 27 + 569 @@ -16324,42 +16465,67 @@ 1 2 - 1361 + 2276 - 2 - 3 - 4084 + 7 + 8 + 1138 - 25 - 26 - 1361 + 17 + 18 + 569 - 71 - 72 - 1361 + 20 + 21 + 569 - 72 - 73 - 1361 + 21 + 22 + 569 + + + 53 + 54 + 569 + + + 54 + 55 + 569 + + + 91 + 92 + 569 119 120 - 1361 + 569 - 371 - 372 - 1361 + 179 + 180 + 569 - 517 - 518 - 1361 + 211 + 212 + 569 + + + 431 + 432 + 569 + + + 646 + 647 + 569 @@ -16375,17 +16541,22 @@ 1 2 - 1501557 + 989074 2 3 - 198755 + 191782 3 - 159 - 83041 + 6 + 107557 + + + 6 + 27 + 65445 @@ -16401,17 +16572,17 @@ 1 2 - 1587322 + 1081267 2 3 - 189226 + 194058 3 - 4 - 6806 + 6 + 78534 @@ -16427,17 +16598,22 @@ 1 2 - 1501557 + 989074 2 3 - 198755 + 191782 3 - 159 - 83041 + 6 + 107557 + + + 6 + 27 + 65445 @@ -16453,7 +16629,7 @@ 1 2 - 1783355 + 1353860 @@ -16466,25 +16642,70 @@ 12 - - 1 - 2 - 160638 - - - 2 - 3 - 34033 - 3 - 24 - 16336 + 5 + 1138 - 34 - 1213 - 5445 + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 55 + 72 + 1138 + + + 83 + 94 + 1138 + + + 115 + 160 + 1138 + + + 204 + 386 + 1138 + + + 939 + 1919 + 1138 @@ -16500,157 +16721,332 @@ 1 2 - 204200 - - - 2 - 9 - 12252 - - - - - - - idx - parent - - - 12 - - - 1 - 2 - 160638 + 2276 2 3 - 34033 + 3983 3 - 24 - 16336 + 5 + 1138 - 34 - 1213 - 5445 - - - - - - - idx - bodydecl - - - 12 - - - 1 - 2 - 160638 + 5 + 6 + 2276 - 2 - 3 - 34033 - - - 3 - 19 - 16336 - - - 29 - 518 - 5445 - - - - - - - bodydecl - id - - - 12 - - - 2 - 3 - 544535 - - - 3 - 4 - 58537 - - - 4 + 6 7 - 53092 + 2276 7 - 162 - 47646 - - - - - - - bodydecl - kind - - - 12 - - - 2 - 3 - 575846 - - - 3 - 4 - 81680 - - - 4 - 7 - 46285 - - - - - - - bodydecl - parent - - - 12 - - - 2 - 3 - 630300 - - - 3 - 8 - 57176 + 9 + 1138 9 - 47 - 16336 + 10 + 1138 + + + 12 + 14 + 1138 + + + 16 + 17 + 569 + + + + + + + idx + parent + + + 12 + + + 3 + 5 + 1138 + + + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 55 + 72 + 1138 + + + 83 + 94 + 1138 + + + 115 + 160 + 1138 + + + 204 + 386 + 1138 + + + 939 + 1919 + 1138 + + + + + + + idx + bodydecl + + + 12 + + + 3 + 5 + 1138 + + + 5 + 6 + 1138 + + + 6 + 7 + 2276 + + + 10 + 15 + 1138 + + + 15 + 16 + 1138 + + + 17 + 20 + 1138 + + + 24 + 32 + 1138 + + + 40 + 43 + 1138 + + + 54 + 56 + 1138 + + + 68 + 87 + 1138 + + + 104 + 138 + 1138 + + + 167 + 226 + 1138 + + + 337 + 647 + 1138 + + + + + + + bodydecl + id + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 157637 + + + 3 + 4 + 38128 + + + 4 + 5 + 33576 + + + 5 + 7 + 24470 + + + 7 + 10 + 29023 + + + 10 + 16 + 30730 + + + 16 + 34 + 27885 + + + 34 + 131 + 8536 + + + + + + + bodydecl + kind + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 193489 + + + 3 + 4 + 77965 + + + 4 + 5 + 29592 + + + 5 + 7 + 33007 + + + 7 + 11 + 15934 + + + + + + + bodydecl + parent + + + 12 + + + 1 + 2 + 17641 + + + 2 + 3 + 261780 + + + 4 + 5 + 33576 + + + 5 + 10 + 31299 + + + 10 + 88 + 23332 @@ -16666,22 +17062,37 @@ 1 2 - 544535 + 175279 2 3 - 92571 + 63737 3 + 4 + 27885 + + + 4 + 5 + 18210 + + + 5 7 - 54453 + 30161 7 - 159 - 12252 + 11 + 29592 + + + 11 + 28 + 22763 @@ -16691,11 +17102,11 @@ exprs - 7411134 + 7410663 id - 7411134 + 7410663 kind @@ -16703,11 +17114,11 @@ typeid - 115983 + 115976 parent - 5075960 + 5075638 idx @@ -16725,7 +17136,7 @@ 1 2 - 7411134 + 7410663 @@ -16741,7 +17152,7 @@ 1 2 - 7411134 + 7410663 @@ -16757,7 +17168,7 @@ 1 2 - 7411134 + 7410663 @@ -16773,7 +17184,7 @@ 1 2 - 7411134 + 7410663 @@ -17028,7 +17439,7 @@ 1 2 - 48884 + 48881 2 @@ -17038,7 +17449,7 @@ 3 6 - 10698 + 10697 6 @@ -17048,12 +17459,12 @@ 10 17 - 9272 + 9271 17 32 - 8723 + 8722 32 @@ -17079,32 +17490,32 @@ 1 2 - 57854 + 57851 2 3 - 18544 + 18543 3 4 - 8915 + 8914 4 5 - 14456 + 14455 5 6 - 9738 + 9737 6 32 - 6474 + 6473 @@ -17120,12 +17531,12 @@ 1 2 - 49048 + 49045 2 3 - 13414 + 13413 3 @@ -17135,7 +17546,7 @@ 5 8 - 8531 + 8530 8 @@ -17155,7 +17566,7 @@ 57 851 - 8723 + 8722 890 @@ -17176,22 +17587,22 @@ 1 2 - 58677 + 58673 2 3 - 18379 + 18378 3 4 - 14731 + 14730 4 5 - 19120 + 19119 5 @@ -17212,17 +17623,17 @@ 1 2 - 3222415 + 3222211 2 3 - 1522711 + 1522614 3 48 - 330833 + 330812 @@ -17238,17 +17649,17 @@ 1 2 - 3525515 + 3525291 2 3 - 1385549 + 1385461 3 8 - 164895 + 164884 @@ -17264,17 +17675,17 @@ 1 2 - 4085819 + 4085559 2 3 - 832130 + 832078 3 10 - 158009 + 157999 @@ -17290,17 +17701,17 @@ 1 2 - 3222415 + 3222211 2 3 - 1522711 + 1522614 3 48 - 330833 + 330812 @@ -17554,15 +17965,15 @@ exprsKotlinType - 7411134 + 7410663 id - 7411134 + 7410663 kttypeid - 12363 + 10930 @@ -17576,7 +17987,7 @@ 1 2 - 7411134 + 7410663 @@ -17592,17 +18003,17 @@ 1 2 - 9272 + 8197 2 3 - 2060 + 1821 - 7180 - 7181 - 1030 + 8123 + 8124 + 910 @@ -17612,15 +18023,15 @@ callableEnclosingExpr - 7299509 + 7299071 id - 7299509 + 7299071 callable_id - 19878 + 19877 @@ -17634,7 +18045,7 @@ 1 2 - 7299509 + 7299071 @@ -17705,7 +18116,7 @@ 73 177 - 1496 + 1495 179 @@ -17725,15 +18136,15 @@ statementEnclosingExpr - 7259150 + 7258714 id - 7259150 + 7258714 statement_id - 525810 + 525778 @@ -17747,7 +18158,7 @@ 1 2 - 7259150 + 7258714 @@ -17763,57 +18174,57 @@ 1 3 - 29127 + 29126 3 5 - 47080 + 47077 5 7 - 48477 + 48474 7 8 - 36044 + 36042 8 9 - 38147 + 38145 9 10 - 50450 + 50447 10 11 - 29214 + 29212 11 12 - 127057 + 127049 12 35 - 35324 + 35322 35 40 - 44626 + 44623 40 81 - 40224 + 40222 82 @@ -17828,11 +18239,11 @@ isParenthesized - 94658 + 94652 id - 94658 + 94652 parentheses @@ -17850,7 +18261,7 @@ 1 2 - 94658 + 94652 @@ -17881,37 +18292,37 @@ when_if - 83383 + 74334 id - 83383 + 74334 when_branch_else - 79912 + 76075 id - 79912 + 76075 callableBinding - 1832402 + 1832520 callerid - 1832402 + 1832520 callee - 263395 + 264311 @@ -17925,7 +18336,7 @@ 1 2 - 1832402 + 1832520 @@ -17941,32 +18352,32 @@ 1 2 - 162234 + 162993 2 3 - 33023 + 33137 3 4 - 16214 + 16271 4 7 - 22259 + 22271 7 20 - 19911 + 19902 20 46115 - 9751 + 9734 @@ -17976,15 +18387,15 @@ memberRefBinding - 23206 + 23208 id - 23206 + 23208 callable - 11196 + 11197 @@ -17998,7 +18409,7 @@ 1 2 - 23206 + 23208 @@ -18014,12 +18425,12 @@ 1 2 - 7861 + 7862 2 3 - 2074 + 2075 3 @@ -18039,15 +18450,15 @@ propertyRefGetBinding - 9639 + 8876 id - 9639 + 8876 getter - 5826 + 5366 @@ -18061,7 +18472,7 @@ 1 2 - 9639 + 8876 @@ -18077,17 +18488,17 @@ 1 2 - 2117 + 1951 2 3 - 3615 + 3328 3 6 - 94 + 86 @@ -18145,15 +18556,15 @@ propertyRefSetBinding - 2671 + 2600 id - 2671 + 2600 setter - 1335 + 1300 @@ -18167,7 +18578,7 @@ 1 2 - 2671 + 2600 @@ -18183,7 +18594,7 @@ 2 3 - 1335 + 1300 @@ -18193,15 +18604,15 @@ variableBinding - 2434432 + 2434277 expr - 2434432 + 2434277 variable - 572564 + 572528 @@ -18215,7 +18626,7 @@ 1 2 - 2434432 + 2434277 @@ -18231,37 +18642,37 @@ 1 2 - 205804 + 205791 2 3 - 120953 + 120945 3 4 - 85027 + 85022 4 5 - 45970 + 45967 5 7 - 40061 + 40059 7 14 - 43075 + 43072 14 464 - 31671 + 31669 @@ -18271,23 +18682,23 @@ localvars - 385297 + 385272 id - 385297 + 385272 nodeName - 140004 + 139995 typeid - 49513 + 49510 parentid - 385297 + 385272 @@ -18301,7 +18712,7 @@ 1 2 - 385297 + 385272 @@ -18317,7 +18728,7 @@ 1 2 - 385297 + 385272 @@ -18333,7 +18744,7 @@ 1 2 - 385297 + 385272 @@ -18349,22 +18760,22 @@ 1 2 - 83661 + 83655 2 3 - 26179 + 26178 3 5 - 10244 + 10243 5 9 - 11951 + 11950 9 @@ -18385,7 +18796,7 @@ 1 2 - 124638 + 124630 2 @@ -18411,22 +18822,22 @@ 1 2 - 83661 + 83655 2 3 - 26179 + 26178 3 5 - 10244 + 10243 5 9 - 11951 + 11950 9 @@ -18447,7 +18858,7 @@ 1 2 - 16504 + 16503 2 @@ -18462,7 +18873,7 @@ 5 6 - 5122 + 5121 6 @@ -18503,7 +18914,7 @@ 1 2 - 23334 + 23332 2 @@ -18513,7 +18924,7 @@ 3 4 - 6260 + 6259 4 @@ -18544,7 +18955,7 @@ 1 2 - 16504 + 16503 2 @@ -18559,7 +18970,7 @@ 5 6 - 5122 + 5121 6 @@ -18600,7 +19011,7 @@ 1 2 - 385297 + 385272 @@ -18616,7 +19027,7 @@ 1 2 - 385297 + 385272 @@ -18632,7 +19043,7 @@ 1 2 - 385297 + 385272 @@ -18642,15 +19053,15 @@ localvarsKotlinType - 227691 + 240107 id - 227691 + 240107 kttypeid - 154 + 1920 @@ -18664,7 +19075,7 @@ 1 2 - 227691 + 240107 @@ -18678,9 +19089,9 @@ 12 - 1470 - 1471 - 154 + 125 + 126 + 1920 @@ -18690,19 +19101,19 @@ namestrings - 4022677 + 4022436 name - 23386 + 23384 value - 22167 + 22166 parent - 4022677 + 4022436 @@ -18716,7 +19127,7 @@ 1 2 - 23386 + 23384 @@ -18732,7 +19143,7 @@ 1 2 - 9605 + 9604 2 @@ -18783,7 +19194,7 @@ 1 2 - 21560 + 21559 2 @@ -18804,7 +19215,7 @@ 1 2 - 9119 + 9118 2 @@ -18855,7 +19266,7 @@ 1 2 - 4022677 + 4022436 @@ -18871,7 +19282,7 @@ 1 2 - 4022677 + 4022436 @@ -18881,15 +19292,15 @@ modules - 7964 + 7965 id - 7964 + 7965 name - 7964 + 7965 @@ -18903,7 +19314,7 @@ 1 2 - 7964 + 7965 @@ -18919,7 +19330,7 @@ 1 2 - 7964 + 7965 @@ -18940,11 +19351,11 @@ cumodule - 247568 + 247580 fileId - 247568 + 247580 moduleId @@ -18962,7 +19373,7 @@ 1 2 - 247568 + 247580 @@ -19013,7 +19424,7 @@ directives - 50277 + 50279 id @@ -19021,7 +19432,7 @@ directive - 50277 + 50279 @@ -19081,7 +19492,7 @@ 1 2 - 50277 + 50279 @@ -19171,15 +19582,15 @@ exports - 35011 + 35013 id - 35011 + 35013 target - 35011 + 35013 @@ -19193,7 +19604,7 @@ 1 2 - 35011 + 35013 @@ -19209,7 +19620,7 @@ 1 2 - 35011 + 35013 @@ -19219,15 +19630,15 @@ exportsTo - 28706 + 28707 id - 12278 + 12279 target - 7466 + 7467 @@ -19241,7 +19652,7 @@ 1 2 - 7300 + 7301 2 @@ -19423,15 +19834,15 @@ uses - 10785 + 10786 id - 10785 + 10786 serviceInterface - 10785 + 10786 @@ -19445,7 +19856,7 @@ 1 2 - 10785 + 10786 @@ -19461,7 +19872,7 @@ 1 2 - 10785 + 10786 @@ -19519,7 +19930,7 @@ providesWith - 5309 + 5310 id @@ -19527,7 +19938,7 @@ serviceImpl - 5309 + 5310 @@ -19572,7 +19983,7 @@ 1 2 - 5309 + 5310 @@ -19582,48 +19993,48 @@ javadoc - 985153 + 985091 id - 985153 + 985091 isNormalComment - 649939 + 649898 commentid - 649939 + 649898 isEolComment - 610101 + 610062 commentid - 610101 + 610062 hasJavadoc - 435379 + 435352 documentableid - 368223 + 368199 javadocid - 435379 + 435352 @@ -19637,12 +20048,12 @@ 1 2 - 320416 + 320396 2 3 - 44960 + 44957 3 @@ -19663,7 +20074,7 @@ 1 2 - 435379 + 435352 @@ -19673,19 +20084,19 @@ javadocTag - 335830 + 335808 id - 335830 + 335808 name - 578 + 577 parentid - 114117 + 114110 idx @@ -19703,7 +20114,7 @@ 1 2 - 335830 + 335808 @@ -19719,7 +20130,7 @@ 1 2 - 335830 + 335808 @@ -19735,7 +20146,7 @@ 1 2 - 335830 + 335808 @@ -19884,37 +20295,37 @@ 1 2 - 33194 + 33192 2 3 - 24937 + 24935 3 4 - 18661 + 18660 4 5 - 13129 + 13128 5 6 - 9991 + 9990 6 7 - 7679 + 7678 7 11 - 6523 + 6522 @@ -19930,22 +20341,22 @@ 1 2 - 39966 + 39963 2 3 - 38644 + 38642 3 4 - 21139 + 21137 4 5 - 12221 + 12220 5 @@ -19966,37 +20377,37 @@ 1 2 - 33194 + 33192 2 3 - 24937 + 24935 3 4 - 18661 + 18660 4 5 - 13129 + 13128 5 6 - 9991 + 9990 6 7 - 7679 + 7678 7 11 - 6523 + 6522 @@ -20184,23 +20595,23 @@ javadocText - 2503007 + 2502848 id - 2503007 + 2502848 text - 1370450 + 1370363 parentid - 1169550 + 1169475 idx - 42115 + 42112 @@ -20214,7 +20625,7 @@ 1 2 - 2503007 + 2502848 @@ -20230,7 +20641,7 @@ 1 2 - 2503007 + 2502848 @@ -20246,7 +20657,7 @@ 1 2 - 2503007 + 2502848 @@ -20262,17 +20673,17 @@ 1 2 - 1139386 + 1139314 2 3 - 149679 + 149670 3 147 - 81384 + 81379 @@ -20288,17 +20699,17 @@ 1 2 - 1140524 + 1140452 2 3 - 149110 + 149101 3 88 - 80815 + 80810 @@ -20314,12 +20725,12 @@ 1 2 - 1346547 + 1346462 2 32 - 23903 + 23901 @@ -20335,22 +20746,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 83092 + 83086 12 75 - 56912 + 56908 @@ -20366,22 +20777,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 84230 + 84225 12 67 - 55774 + 55770 @@ -20397,22 +20808,22 @@ 1 2 - 870190 + 870135 2 3 - 159354 + 159344 3 12 - 83092 + 83086 12 75 - 56912 + 56908 @@ -20428,7 +20839,7 @@ 2 3 - 21057 + 21056 3 @@ -20484,7 +20895,7 @@ 2 3 - 20488 + 20487 3 @@ -20535,7 +20946,7 @@ 2 3 - 21057 + 21056 3 @@ -20580,15 +20991,15 @@ xmlEncoding - 800467 + 1129463 id - 800467 + 1129463 encoding - 1361 + 1920 @@ -20602,7 +21013,7 @@ 1 2 - 800467 + 1129463 @@ -20618,7 +21029,7 @@ 588 589 - 1361 + 1920 @@ -20976,27 +21387,27 @@ xmlElements - 106507143 + 150282022 id - 106507143 + 150282022 name - 337612 + 476372 parentid - 2747183 + 3876287 idx - 1207508 + 1703799 fileid - 800467 + 1129463 @@ -21010,7 +21421,7 @@ 1 2 - 106507143 + 150282022 @@ -21026,7 +21437,7 @@ 1 2 - 106507143 + 150282022 @@ -21042,7 +21453,7 @@ 1 2 - 106507143 + 150282022 @@ -21058,7 +21469,7 @@ 1 2 - 106507143 + 150282022 @@ -21074,57 +21485,57 @@ 1 2 - 106184 + 149826 2 3 - 40840 + 57625 3 4 - 16336 + 23050 4 6 - 29949 + 42258 6 8 - 24504 + 34575 8 9 - 12252 + 17287 9 10 - 23142 + 32654 10 18 - 28588 + 40337 18 48 - 25865 + 36496 52 250 - 25865 + 36496 342 73380 - 4084 + 5762 @@ -21140,52 +21551,52 @@ 1 2 - 123881 + 174797 2 3 - 46285 + 65309 3 4 - 17697 + 24971 4 5 - 14974 + 21129 5 6 - 19058 + 26891 6 8 - 28588 + 40337 8 10 - 28588 + 40337 10 21 - 27226 + 38417 22 128 - 25865 + 36496 130 229 - 5445 + 7683 @@ -21201,37 +21612,37 @@ 1 2 - 186503 + 263157 2 3 - 49008 + 69150 3 4 - 24504 + 34575 4 6 - 20420 + 28812 6 9 - 20420 + 28812 9 38 - 25865 + 36496 45 888 - 10890 + 15366 @@ -21247,42 +21658,42 @@ 1 2 - 183780 + 259315 2 3 - 36756 + 51863 3 4 - 17697 + 24971 4 5 - 13613 + 19208 5 7 - 29949 + 42258 7 16 - 25865 + 36496 17 114 - 27226 + 38417 118 131 - 2722 + 3841 @@ -21298,32 +21709,32 @@ 1 2 - 1671725 + 2358811 2 3 - 428822 + 605069 3 4 - 178335 + 251632 4 8 - 213730 + 301574 8 777 - 224621 + 316941 777 888 - 29949 + 42258 @@ -21339,17 +21750,17 @@ 1 2 - 2267992 + 3200146 2 3 - 291326 + 411063 3 17 - 187864 + 265078 @@ -21365,32 +21776,32 @@ 1 2 - 1671725 + 2358811 2 3 - 428822 + 605069 3 4 - 178335 + 251632 4 8 - 213730 + 301574 8 777 - 224621 + 316941 777 888 - 29949 + 42258 @@ -21406,7 +21817,7 @@ 1 2 - 2747183 + 3876287 @@ -21422,67 +21833,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 159 - 91209 + 128697 162 2019 - 13613 + 19208 @@ -21498,22 +21909,22 @@ 1 2 - 978803 + 1381095 2 5 - 89848 + 126776 5 9 - 103461 + 145985 9 150 - 35394 + 49942 @@ -21529,67 +21940,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 159 - 91209 + 128697 162 2019 - 13613 + 19208 @@ -21605,67 +22016,67 @@ 2 8 - 102100 + 144064 9 76 - 96655 + 136380 76 82 - 91209 + 128697 82 89 - 87125 + 122934 89 92 - 78957 + 111409 92 95 - 95293 + 134459 95 97 - 106184 + 149826 97 98 - 149747 + 211294 98 99 - 92571 + 130618 99 104 - 110268 + 155589 104 106 - 92571 + 130618 106 139 - 91209 + 128697 141 589 - 13613 + 19208 @@ -21681,57 +22092,57 @@ 1 2 - 58537 + 82596 2 3 - 134772 + 190164 3 4 - 176974 + 249711 4 5 - 74873 + 105647 5 7 - 59898 + 84517 7 10 - 66705 + 94121 10 31 - 62621 + 88359 35 694 - 61260 + 86438 738 776 - 20420 + 28812 777 779 - 65344 + 92201 788 889 - 19058 + 26891 @@ -21747,37 +22158,37 @@ 1 2 - 58537 + 82596 2 3 - 398872 + 562810 3 4 - 138856 + 195927 4 5 - 65344 + 92201 5 6 - 61260 + 86438 6 9 - 65344 + 92201 9 69 - 12252 + 17287 @@ -21793,27 +22204,27 @@ 1 2 - 58537 + 82596 2 3 - 567678 + 800997 3 4 - 57176 + 80675 4 6 - 58537 + 82596 6 165 - 58537 + 82596 @@ -21829,42 +22240,42 @@ 1 2 - 202839 + 286207 2 3 - 219175 + 309257 3 4 - 88487 + 124855 4 7 - 66705 + 94121 7 17 - 66705 + 94121 18 763 - 61260 + 86438 764 777 - 65344 + 92201 777 888 - 29949 + 42258 @@ -21874,31 +22285,31 @@ xmlAttrs - 129551904 + 182798274 id - 129551904 + 182798274 elementid - 105600491 + 149002731 name - 511863 + 722241 value - 8184375 + 11548187 idx - 31310 + 44179 fileid - 799106 + 1127542 @@ -21912,7 +22323,7 @@ 1 2 - 129551904 + 182798274 @@ -21928,7 +22339,7 @@ 1 2 - 129551904 + 182798274 @@ -21944,7 +22355,7 @@ 1 2 - 129551904 + 182798274 @@ -21960,7 +22371,7 @@ 1 2 - 129551904 + 182798274 @@ -21976,7 +22387,7 @@ 1 2 - 129551904 + 182798274 @@ -21992,17 +22403,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7940695 + 11204353 6 24 - 1025088 + 1446404 @@ -22018,17 +22429,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7954308 + 11223562 6 23 - 1011475 + 1427196 @@ -22044,17 +22455,17 @@ 1 2 - 96687799 + 136426886 2 6 - 7993787 + 11279267 6 21 - 918904 + 1296577 @@ -22070,17 +22481,17 @@ 1 2 - 96634707 + 136351973 2 6 - 7940695 + 11204353 6 24 - 1025088 + 1446404 @@ -22096,7 +22507,7 @@ 1 2 - 105600491 + 149002731 @@ -22112,62 +22523,62 @@ 1 2 - 106184 + 149826 2 3 - 55814 + 78755 3 4 - 31310 + 44179 4 5 - 17697 + 24971 5 6 - 29949 + 42258 6 8 - 36756 + 51863 8 11 - 42201 + 59546 11 22 - 39478 + 55704 23 38 - 40840 + 57625 38 79 - 40840 + 57625 81 168 - 39478 + 55704 168 74700 - 31310 + 44179 @@ -22183,62 +22594,62 @@ 1 2 - 106184 + 149826 2 3 - 55814 + 78755 3 4 - 31310 + 44179 4 5 - 17697 + 24971 5 6 - 29949 + 42258 6 8 - 36756 + 51863 8 11 - 46285 + 65309 11 25 - 43562 + 61467 25 39 - 42201 + 59546 43 91 - 40840 + 57625 91 227 - 39478 + 55704 227 74700 - 21781 + 30733 @@ -22254,42 +22665,42 @@ 1 2 - 215091 + 303495 2 3 - 80319 + 113330 3 4 - 34033 + 48021 4 5 - 36756 + 51863 5 9 - 42201 + 59546 9 21 - 39478 + 55704 22 64 - 42201 + 59546 68 2100 - 21781 + 30733 @@ -22305,37 +22716,37 @@ 1 2 - 201478 + 284286 2 3 - 95293 + 134459 3 4 - 49008 + 69150 4 5 - 54453 + 76834 5 7 - 32672 + 46100 7 10 - 40840 + 57625 10 21 - 38117 + 53783 @@ -22351,52 +22762,52 @@ 1 2 - 178335 + 251632 2 3 - 53092 + 74913 3 4 - 27226 + 38417 4 5 - 24504 + 34575 5 6 - 38117 + 53783 6 9 - 42201 + 59546 9 17 - 44924 + 63388 17 34 - 39478 + 55704 36 91 - 39478 + 55704 91 223 - 24504 + 34575 @@ -22412,37 +22823,37 @@ 1 2 - 4470639 + 6308091 2 3 - 1210231 + 1707641 3 5 - 627577 + 885514 5 31 - 616686 + 870147 31 91 - 643913 + 908564 91 1111 - 613964 + 866306 3397 3398 - 1361 + 1920 @@ -22458,32 +22869,32 @@ 1 2 - 4560488 + 6434868 2 3 - 1153054 + 1626965 3 5 - 635745 + 897039 5 33 - 645275 + 910485 33 93 - 631661 + 891277 93 3398 - 558149 + 787551 @@ -22499,17 +22910,17 @@ 1 2 - 7427470 + 10480191 2 4 - 658888 + 929694 4 53 - 98016 + 138301 @@ -22525,17 +22936,17 @@ 1 2 - 6778110 + 9563942 2 3 - 989694 + 1396462 3 20 - 416569 + 587781 @@ -22551,32 +22962,32 @@ 1 2 - 5268385 + 7433713 2 3 - 887593 + 1252398 3 10 - 635745 + 897039 10 83 - 622132 + 877831 83 99 - 624854 + 881672 99 182 - 145663 + 205531 @@ -22592,62 +23003,62 @@ 1 6 - 2722 + 3841 12 14 - 2722 + 3841 17 26 - 2722 + 3841 39 56 - 2722 + 3841 83 110 - 2722 + 3841 153 232 - 2722 + 3841 316 400 - 2722 + 3841 468 545 - 2722 + 3841 626 754 - 2722 + 3841 951 1491 - 2722 + 3841 4718 6587 - 2722 + 3841 77571 77572 - 1361 + 1920 @@ -22663,62 +23074,62 @@ 1 6 - 2722 + 3841 12 14 - 2722 + 3841 17 26 - 2722 + 3841 39 56 - 2722 + 3841 83 110 - 2722 + 3841 153 232 - 2722 + 3841 316 400 - 2722 + 3841 468 545 - 2722 + 3841 626 754 - 2722 + 3841 951 1491 - 2722 + 3841 4718 6587 - 2722 + 3841 77571 77572 - 1361 + 1920 @@ -22734,62 +23145,62 @@ 1 4 - 2722 + 3841 7 10 - 2722 + 3841 11 17 - 2722 + 3841 18 23 - 2722 + 3841 26 38 - 2722 + 3841 39 49 - 2722 + 3841 57 67 - 2722 + 3841 72 79 - 2722 + 3841 95 101 - 2722 + 3841 105 106 - 2722 + 3841 106 132 - 2722 + 3841 140 141 - 1361 + 1920 @@ -22805,62 +23216,62 @@ 1 5 - 2722 + 3841 7 10 - 2722 + 3841 11 18 - 2722 + 3841 22 32 - 2722 + 3841 46 63 - 2722 + 3841 85 119 - 2722 + 3841 142 185 - 2722 + 3841 212 228 - 2722 + 3841 253 275 - 2722 + 3841 307 423 - 2722 + 3841 580 1324 - 2722 + 3841 3579 3580 - 1361 + 1920 @@ -22876,62 +23287,62 @@ 1 6 - 2722 + 3841 7 8 - 2722 + 3841 10 19 - 2722 + 3841 23 36 - 2722 + 3841 45 59 - 2722 + 3841 73 97 - 2722 + 3841 115 131 - 2722 + 3841 140 148 - 2722 + 3841 168 181 - 2722 + 3841 248 363 - 2722 + 3841 473 530 - 2722 + 3841 587 588 - 1361 + 1920 @@ -22947,72 +23358,72 @@ 1 3 - 59898 + 84517 3 5 - 61260 + 86438 5 6 - 36756 + 51863 6 7 - 61260 + 86438 7 8 - 51730 + 72992 8 10 - 58537 + 82596 10 15 - 65344 + 92201 15 27 - 61260 + 86438 27 41 - 61260 + 86438 41 65 - 61260 + 86438 65 157 - 65344 + 92201 162 817 - 61260 + 86438 818 832 - 66705 + 94121 832 1187 - 27226 + 38417 @@ -23028,52 +23439,52 @@ 1 2 - 91209 + 128697 2 3 - 187864 + 265078 3 4 - 112991 + 159431 4 5 - 77596 + 109488 5 8 - 72151 + 101805 8 14 - 61260 + 86438 14 295 - 61260 + 86438 330 775 - 50369 + 71071 776 778 - 65344 + 92201 787 888 - 19058 + 26891 @@ -23089,62 +23500,62 @@ 1 2 - 50369 + 71071 2 3 - 65344 + 92201 3 4 - 50369 + 71071 4 5 - 66705 + 94121 5 6 - 121159 + 170956 6 7 - 114352 + 161351 7 8 - 50369 + 71071 8 12 - 61260 + 86438 12 18 - 69428 + 97963 18 24 - 68066 + 96042 24 37 - 62621 + 88359 37 55 - 19058 + 26891 @@ -23160,67 +23571,67 @@ 1 3 - 69428 + 97963 3 4 - 39478 + 55704 4 5 - 73512 + 103726 5 6 - 88487 + 124855 6 8 - 62621 + 88359 8 12 - 70789 + 99884 12 19 - 61260 + 86438 19 27 - 69428 + 97963 27 41 - 61260 + 86438 42 170 - 61260 + 86438 205 780 - 57176 + 80675 781 783 - 65344 + 92201 791 893 - 19058 + 26891 @@ -23236,47 +23647,47 @@ 1 2 - 78957 + 111409 2 3 - 76235 + 107567 3 4 - 151108 + 213215 4 5 - 155192 + 218977 5 6 - 92571 + 130618 6 10 - 68066 + 96042 10 12 - 46285 + 65309 12 15 - 69428 + 97963 15 24 - 61260 + 86438 @@ -23286,23 +23697,23 @@ xmlNs - 1283743 + 1811367 id - 8168 + 11525 prefixName - 9529 + 13445 URI - 8168 + 11525 fileid - 747375 + 1054550 @@ -23316,12 +23727,12 @@ 1 2 - 6806 + 9604 2 3 - 1361 + 1920 @@ -23337,7 +23748,7 @@ 1 2 - 8168 + 11525 @@ -23353,32 +23764,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 167 168 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23394,7 +23805,7 @@ 1 2 - 9529 + 13445 @@ -23410,7 +23821,7 @@ 1 2 - 9529 + 13445 @@ -23426,37 +23837,37 @@ 1 2 - 1361 + 1920 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 166 167 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23472,7 +23883,7 @@ 1 2 - 8168 + 11525 @@ -23488,12 +23899,12 @@ 1 2 - 6806 + 9604 2 3 - 1361 + 1920 @@ -23509,32 +23920,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 88 89 - 1361 + 1920 167 168 - 1361 + 1920 213 214 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23550,17 +23961,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23576,17 +23987,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23602,17 +24013,17 @@ 1 2 - 333528 + 470609 2 3 - 291326 + 411063 3 4 - 122520 + 172877 @@ -23622,19 +24033,19 @@ xmlHasNs - 25896767 + 36540446 elementId - 25896767 + 36540446 nsId - 8168 + 11525 fileid - 743291 + 1048787 @@ -23648,7 +24059,7 @@ 1 2 - 25896767 + 36540446 @@ -23664,7 +24075,7 @@ 1 2 - 25896767 + 36540446 @@ -23680,32 +24091,32 @@ 13 14 - 1361 + 1920 84 85 - 1361 + 1920 2426 2427 - 1361 + 1920 2733 2734 - 1361 + 1920 3704 3705 - 1361 + 1920 10063 10064 - 1361 + 1920 @@ -23721,32 +24132,32 @@ 2 3 - 1361 + 1920 20 21 - 1361 + 1920 86 87 - 1361 + 1920 164 165 - 1361 + 1920 209 210 - 1361 + 1920 453 454 - 1361 + 1920 @@ -23762,77 +24173,77 @@ 1 3 - 44924 + 63388 3 5 - 62621 + 88359 5 6 - 34033 + 48021 6 7 - 65344 + 92201 7 8 - 49008 + 69150 8 10 - 61260 + 86438 10 15 - 65344 + 92201 15 25 - 55814 + 78755 25 36 - 57176 + 80675 36 49 - 58537 + 82596 49 54 - 14974 + 21129 54 55 - 58537 + 82596 55 81 - 57176 + 80675 81 298 - 55814 + 78755 298 833 - 2722 + 3841 @@ -23848,17 +24259,17 @@ 1 2 - 334889 + 472530 2 3 - 288604 + 407221 3 4 - 119797 + 169035 @@ -23868,23 +24279,23 @@ xmlComments - 107198704 + 151257816 id - 107198704 + 151257816 text - 1692145 + 2387624 parentid - 839946 + 1185168 fileid - 785493 + 1108333 @@ -23898,7 +24309,7 @@ 1 2 - 107198704 + 151257816 @@ -23914,7 +24325,7 @@ 1 2 - 107198704 + 151257816 @@ -23930,7 +24341,7 @@ 1 2 - 107198704 + 151257816 @@ -23946,67 +24357,67 @@ 1 2 - 232789 + 328466 2 7 - 138856 + 195927 7 32 - 140218 + 197848 32 61 - 127965 + 180560 61 76 - 127965 + 180560 76 84 - 136133 + 192085 84 90 - 125243 + 176718 90 94 - 111629 + 157510 94 95 - 59898 + 84517 95 96 - 100739 + 142143 96 98 - 140218 + 197848 98 100 - 126604 + 178639 100 460 - 123881 + 174797 @@ -24022,67 +24433,67 @@ 1 2 - 235511 + 332308 2 6 - 134772 + 190164 6 32 - 142940 + 201689 32 61 - 129327 + 182481 61 75 - 132049 + 186323 75 84 - 148386 + 209373 84 90 - 122520 + 172877 90 94 - 119797 + 169035 94 95 - 66705 + 94121 95 96 - 103461 + 145985 96 98 - 142940 + 201689 98 100 - 134772 + 190164 100 460 - 78957 + 111409 @@ -24098,67 +24509,67 @@ 1 2 - 246402 + 347674 2 7 - 133411 + 188243 7 32 - 133411 + 188243 32 61 - 129327 + 182481 61 75 - 132049 + 186323 75 84 - 148386 + 209373 84 90 - 122520 + 172877 90 94 - 119797 + 169035 94 95 - 66705 + 94121 95 96 - 103461 + 145985 96 98 - 142940 + 201689 98 100 - 134772 + 190164 100 460 - 78957 + 111409 @@ -24174,22 +24585,22 @@ 1 2 - 668417 + 943140 2 724 - 63982 + 90280 726 830 - 77596 + 109488 831 941 - 29949 + 42258 @@ -24205,27 +24616,27 @@ 1 2 - 668417 + 943140 2 697 - 63982 + 90280 697 795 - 34033 + 48021 795 827 - 63982 + 90280 838 899 - 9529 + 13445 @@ -24241,7 +24652,7 @@ 1 2 - 839946 + 1185168 @@ -24257,27 +24668,27 @@ 1 2 - 600350 + 847097 2 549 - 59898 + 84517 579 829 - 40840 + 57625 829 832 - 65344 + 92201 834 941 - 19058 + 26891 @@ -24293,27 +24704,27 @@ 1 2 - 600350 + 847097 2 536 - 59898 + 84517 560 795 - 51730 + 72992 795 812 - 59898 + 84517 819 899 - 13613 + 19208 @@ -24329,12 +24740,12 @@ 1 2 - 746014 + 1052629 2 6 - 39478 + 55704 @@ -24344,31 +24755,31 @@ xmlChars - 101302741 + 142938589 id - 101302741 + 142938589 text - 77797848 + 109773086 parentid - 101302741 + 142938589 idx - 1361 + 1920 isCDATA - 2722 + 3841 fileid - 176974 + 249711 @@ -24382,7 +24793,7 @@ 1 2 - 101302741 + 142938589 @@ -24398,7 +24809,7 @@ 1 2 - 101302741 + 142938589 @@ -24414,7 +24825,7 @@ 1 2 - 101302741 + 142938589 @@ -24430,7 +24841,7 @@ 1 2 - 101302741 + 142938589 @@ -24446,7 +24857,7 @@ 1 2 - 101302741 + 142938589 @@ -24462,17 +24873,17 @@ 1 2 - 66568156 + 93927944 2 3 - 6991841 + 9865517 3 128 - 4237850 + 5979625 @@ -24488,17 +24899,17 @@ 1 2 - 66568156 + 93927944 2 3 - 6991841 + 9865517 3 128 - 4237850 + 5979625 @@ -24514,7 +24925,7 @@ 1 2 - 77797848 + 109773086 @@ -24530,7 +24941,7 @@ 1 2 - 77797848 + 109773086 @@ -24546,12 +24957,12 @@ 1 2 - 74436700 + 105030493 2 76 - 3361148 + 4742593 @@ -24567,7 +24978,7 @@ 1 2 - 101302741 + 142938589 @@ -24583,7 +24994,7 @@ 1 2 - 101302741 + 142938589 @@ -24599,7 +25010,7 @@ 1 2 - 101302741 + 142938589 @@ -24615,7 +25026,7 @@ 1 2 - 101302741 + 142938589 @@ -24631,7 +25042,7 @@ 1 2 - 101302741 + 142938589 @@ -24647,7 +25058,7 @@ 74414 74415 - 1361 + 1920 @@ -24663,7 +25074,7 @@ 57148 57149 - 1361 + 1920 @@ -24679,7 +25090,7 @@ 74414 74415 - 1361 + 1920 @@ -24695,7 +25106,7 @@ 2 3 - 1361 + 1920 @@ -24711,7 +25122,7 @@ 130 131 - 1361 + 1920 @@ -24727,12 +25138,12 @@ 518 519 - 1361 + 1920 73896 73897 - 1361 + 1920 @@ -24748,12 +25159,12 @@ 492 493 - 1361 + 1920 56656 56657 - 1361 + 1920 @@ -24769,12 +25180,12 @@ 518 519 - 1361 + 1920 73896 73897 - 1361 + 1920 @@ -24790,7 +25201,7 @@ 1 2 - 2722 + 3841 @@ -24806,12 +25217,12 @@ 98 99 - 1361 + 1920 130 131 - 1361 + 1920 @@ -24827,57 +25238,57 @@ 1 2 - 14974 + 21129 2 23 - 13613 + 19208 24 243 - 13613 + 19208 294 566 - 13613 + 19208 610 686 - 13613 + 19208 691 764 - 13613 + 19208 765 775 - 13613 + 19208 775 776 - 4084 + 5762 776 777 - 49008 + 69150 777 803 - 13613 + 19208 807 888 - 13613 + 19208 @@ -24893,67 +25304,67 @@ 1 2 - 14974 + 21129 2 21 - 13613 + 19208 22 188 - 13613 + 19208 208 492 - 13613 + 19208 525 589 - 13613 + 19208 590 638 - 13613 + 19208 639 651 - 13613 + 19208 652 656 - 12252 + 17287 656 659 - 16336 + 23050 659 663 - 14974 + 21129 663 667 - 13613 + 19208 667 701 - 13613 + 19208 702 744 - 9529 + 13445 @@ -24969,57 +25380,57 @@ 1 2 - 14974 + 21129 2 23 - 13613 + 19208 24 243 - 13613 + 19208 294 566 - 13613 + 19208 610 686 - 13613 + 19208 691 764 - 13613 + 19208 765 775 - 13613 + 19208 775 776 - 4084 + 5762 776 777 - 49008 + 69150 777 803 - 13613 + 19208 807 888 - 13613 + 19208 @@ -25035,7 +25446,7 @@ 1 2 - 176974 + 249711 @@ -25051,12 +25462,12 @@ 1 2 - 43562 + 61467 2 3 - 133411 + 188243 @@ -25066,15 +25477,15 @@ xmllocations - 446644705 + 630217533 xmlElement - 445369130 + 628417691 location - 418533038 + 590551854 @@ -25088,12 +25499,12 @@ 1 2 - 445360961 + 628406166 2 454 - 8168 + 11525 @@ -25109,12 +25520,12 @@ 1 2 - 409045860 + 577165407 2 25 - 9487177 + 13386446 @@ -25355,19 +25766,19 @@ ktComments - 133411 + 188243 id - 133411 + 188243 kind - 4084 + 5762 text - 96655 + 136380 @@ -25381,7 +25792,7 @@ 1 2 - 133411 + 188243 @@ -25397,7 +25808,7 @@ 1 2 - 133411 + 188243 @@ -25413,17 +25824,17 @@ 16 17 - 1361 + 1920 22 23 - 1361 + 1920 60 61 - 1361 + 1920 @@ -25439,17 +25850,17 @@ 1 2 - 1361 + 1920 16 17 - 1361 + 1920 54 55 - 1361 + 1920 @@ -25465,12 +25876,12 @@ 1 2 - 92571 + 130618 4 23 - 4084 + 5762 @@ -25486,7 +25897,7 @@ 1 2 - 96655 + 136380 @@ -25496,19 +25907,19 @@ ktCommentSections - 59896 + 52611 id - 59896 + 52611 comment - 54765 + 48161 content - 50913 + 44765 @@ -25522,7 +25933,7 @@ 1 2 - 59896 + 52611 @@ -25538,7 +25949,7 @@ 1 2 - 59896 + 52611 @@ -25554,12 +25965,12 @@ 1 2 - 52697 + 46367 2 18 - 2068 + 1793 @@ -25575,12 +25986,12 @@ 1 2 - 52697 + 46367 2 18 - 2068 + 1793 @@ -25596,17 +26007,17 @@ 1 2 - 45040 + 39616 2 3 - 4909 + 4313 3 63 - 963 + 835 @@ -25622,17 +26033,17 @@ 1 2 - 45151 + 39712 2 3 - 4815 + 4231 3 56 - 947 + 821 @@ -25642,15 +26053,15 @@ ktCommentSectionNames - 5130 + 4450 id - 5130 + 4450 name - 15 + 13 @@ -25664,7 +26075,7 @@ 1 2 - 5130 + 4450 @@ -25680,7 +26091,7 @@ 325 326 - 15 + 13 @@ -25690,15 +26101,15 @@ ktCommentSectionSubjectNames - 5130 + 4450 id - 5130 + 4450 subjectname - 3362 + 2916 @@ -25712,7 +26123,7 @@ 1 2 - 5130 + 4450 @@ -25728,22 +26139,22 @@ 1 2 - 2557 + 2218 2 3 - 505 + 438 3 9 - 252 + 219 10 16 - 47 + 41 @@ -25753,15 +26164,15 @@ ktCommentOwners - 85377 + 75329 id - 54008 + 47914 owner - 83356 + 73508 @@ -25775,22 +26186,22 @@ 1 2 - 34510 + 30838 2 3 - 12361 + 10872 3 4 - 4641 + 4025 4 6 - 2494 + 2177 @@ -25806,12 +26217,12 @@ 1 2 - 81335 + 71701 2 - 3 - 2020 + 4 + 1807 @@ -25821,19 +26232,19 @@ ktExtensionFunctions - 702451 + 1206297 id - 702451 + 1206297 typeid - 84403 + 97963 kttypeid - 1361 + 1920 @@ -25847,7 +26258,7 @@ 1 2 - 702451 + 1206297 @@ -25863,7 +26274,7 @@ 1 2 - 702451 + 1206297 @@ -25879,37 +26290,37 @@ 1 2 - 53092 + 55704 2 3 - 5445 + 5762 3 4 - 2722 - - - 4 - 5 - 6806 + 3841 5 - 12 - 6806 + 6 + 13445 - 12 - 69 - 6806 + 7 + 16 + 7683 - 84 - 174 - 2722 + 20 + 87 + 7683 + + + 109 + 227 + 3841 @@ -25925,7 +26336,7 @@ 1 2 - 84403 + 97963 @@ -25939,9 +26350,9 @@ 12 - 516 - 517 - 1361 + 628 + 629 + 1920 @@ -25955,9 +26366,9 @@ 12 - 62 - 63 - 1361 + 51 + 52 + 1920 @@ -25967,15 +26378,15 @@ ktProperties - 30236718 + 21895839 id - 30236718 + 21895839 nodeName - 10667458 + 13542035 @@ -25989,7 +26400,7 @@ 1 2 - 30236718 + 21895839 @@ -26005,22 +26416,17 @@ 1 2 - 7868544 + 11824790 2 - 3 - 1212953 + 4 + 1142909 - 3 - 8 - 807274 - - - 8 - 554 - 778686 + 4 + 352 + 574335 @@ -26030,15 +26436,15 @@ ktPropertyGetters - 4557765 + 5985387 id - 4557765 + 5985387 getter - 4557765 + 5985387 @@ -26052,7 +26458,7 @@ 1 2 - 4557765 + 5985387 @@ -26068,7 +26474,7 @@ 1 2 - 4557765 + 5985387 @@ -26078,15 +26484,15 @@ ktPropertySetters - 264099 + 366883 id - 264099 + 366883 setter - 264099 + 366883 @@ -26100,7 +26506,7 @@ 1 2 - 264099 + 366883 @@ -26116,7 +26522,7 @@ 1 2 - 264099 + 366883 @@ -26126,15 +26532,15 @@ ktPropertyBackingFields - 23552540 + 14423708 id - 23552540 + 14423708 backingField - 23552540 + 14423708 @@ -26148,7 +26554,7 @@ 1 2 - 23552540 + 14423708 @@ -26164,7 +26570,7 @@ 1 2 - 23552540 + 14423708 @@ -26174,15 +26580,15 @@ ktSyntheticBody - 10303 + 9108 id - 10303 + 9108 kind - 2060 + 1821 @@ -26196,7 +26602,7 @@ 1 2 - 10303 + 9108 @@ -26212,7 +26618,7 @@ 5 6 - 2060 + 1821 @@ -26222,37 +26628,37 @@ ktLocalFunction - 2722 + 3841 id - 2722 + 3841 ktInitializerAssignment - 392065 + 199475 id - 392065 + 199475 ktPropertyDelegates - 5650 + 5201 id - 5650 + 5201 variableId - 5650 + 5201 @@ -26266,7 +26672,7 @@ 1 2 - 5650 + 5201 @@ -26282,7 +26688,7 @@ 1 2 - 5650 + 5201 @@ -26292,15 +26698,15 @@ compiler_generated - 533645 + 1467534 id - 533645 + 1467534 kind - 5445 + 13445 @@ -26314,7 +26720,7 @@ 1 2 - 533645 + 1467534 @@ -26328,24 +26734,39 @@ 12 - 2 - 3 - 1361 + 1 + 2 + 1920 8 9 - 1361 + 1920 + + + 38 + 39 + 1920 81 82 - 1361 + 1920 - 301 - 302 - 1361 + 85 + 86 + 1920 + + + 236 + 237 + 1920 + + + 315 + 316 + 1920 @@ -26355,15 +26776,15 @@ ktFunctionOriginalNames - 1215676 + 1586627 id - 1215676 + 1586627 name - 138856 + 186323 @@ -26377,7 +26798,7 @@ 1 2 - 1215676 + 1586627 @@ -26393,22 +26814,22 @@ 1 2 - 111629 + 147905 2 - 7 - 10890 + 4 + 13445 - 7 - 31 - 10890 + 6 + 16 + 15366 - 92 - 380 - 5445 + 22 + 339 + 9604 @@ -26418,11 +26839,11 @@ ktDataClasses - 80319 + 113330 id - 80319 + 113330 diff --git a/java/ql/lib/ext/android.app.model.yml b/java/ql/lib/ext/android.app.model.yml new file mode 100644 index 00000000000..82ed724a418 --- /dev/null +++ b/java/ql/lib/ext/android.app.model.yml @@ -0,0 +1,147 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.app", "Activity", True, "bindService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "bindServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "setResult", "(int,Intent)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "Activity", True, "startActivityAsCaller", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int)", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int,Bundle)", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(String,Intent,int,Bundle)", "", "Argument[1]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityForResultAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "AlarmManager", True, "set", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setAlarmClock", "", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setExact", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setExactAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setInexactRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "setWindow", "(int,long,long,PendingIntent)", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsPackage", "(String,String,int,Notification)", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsUser", "(String,int,Notification,UserHandle)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String,Bundle)", "", "Argument[2]", "pending-intent-sent", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.app", "Notification$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(Icon,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "addRemoteInput", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Action$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setAllowGeneratedReplies", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setAuthenticationRequired", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setContextual", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Action$Builder", True, "setSemanticAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "BigPictureStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "bigLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "bigPicture", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigPictureStyle", True, "showBigPictureWhenCollapsed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "BigTextStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "bigText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$BigTextStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "addPerson", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.Field[android.app.Notification.extras]", "value", "manual"] + - ["android.app", "Notification$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "recoverBuilder", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setActions", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setActions", "", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setAutoCancel", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setBadgeIconType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setBubbleMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setChannelId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setChronometerCountDown", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setColorized", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setContentText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCustomBigContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setCustomHeadsUpContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDefaults", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDeleteIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setDeleteIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setExtras", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setFlag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setForegroundServiceBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setFullScreenIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroup", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroupAlertBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setGroupSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLights", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLocalOnly", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setLocusId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setNumber", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setOngoing", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setOnlyAlertOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setProgress", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPublicVersion", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setPublicVersion", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$Builder", True, "setRemoteInputHistory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSettingsText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setShortcutId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setShowWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSmallIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSortKey", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSound", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setStyle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setSubText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setTicker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setTimeoutAfter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setUsesChronometer", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setVibrate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setVisibility", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Builder", True, "setWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "InboxStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$InboxStyle", True, "addLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$InboxStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$MediaStyle", True, "MediaStyle", "(Builder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.app", "Notification$MediaStyle", True, "setMediaSession", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$MediaStyle", True, "setShowActionsInCompactView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.app", "Notification$Style", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.content.model.yml b/java/ql/lib/ext/android.content.model.yml new file mode 100644 index 00000000000..292360c550c --- /dev/null +++ b/java/ql/lib/ext/android.content.model.yml @@ -0,0 +1,225 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + # ContentInterface models are here for backwards compatibility (it was removed in API 28) + - ["android.content", "ContentInterface", True, "call", "(String,String,String,Bundle)", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "delete", "(Uri,Bundle)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "getType", "(Uri)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "insert", "(Uri,ContentValues,Bundle)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openAssetFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "openTypedAssetFile", "(Uri,String,Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "query", "(Uri,String[],Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentInterface", True, "update", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "call", "(String,String,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "call", "(String,String,String,Bundle)", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "delete", "(Uri,Bundle)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "getType", "(Uri)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "insert", "(Uri,ContentValues)", "", "Parameter[0..1]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "insert", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openAssetFile", "(Uri,String)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openAssetFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openFile", "(Uri,String)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openFile", "(Uri,String,CancellationSignal)", "", "Parameter[0]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openTypedAssetFile", "(Uri,String,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "openTypedAssetFile", "(Uri,String,Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],Bundle,CancellationSignal)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Parameter[0..4]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Parameter[0..4]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,Bundle)", "", "Parameter[0..2]", "contentprovider", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Parameter[0..3]", "contentprovider", "manual"] + - ["android.content", "Context", True, "getExternalCacheDir", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalCacheDirs", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalFilesDir", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.content", "Context", True, "getExternalFilesDirs", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentResolver", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.content", "Context", True, "sendBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendBroadcastWithMultiplePermissions", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcast", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivities", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivity", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityFromChild", "", "", "Argument[1]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityFromFragment", "", "", "Argument[1]", "intent-start", "manual"] + - ["android.content", "Context", True, "startActivityIfNeeded", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startForegroundService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startService", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "startServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.content", "ComponentName", False, "ComponentName", "(Context,Class)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(Context,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(Parcel)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "ComponentName", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ComponentName", False, "createRelative", "(Context,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "createRelative", "(String,String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "flattenToShortString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "flattenToString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getClassName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getPackageName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "getShortClassName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ComponentName", False, "unflattenFromString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # ContentProviderClient is tainted at its creation, not by its arguments + - ["android.content", "ContentProviderClient", True, "applyBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "call", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "canonicalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "getLocalContentProvider", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "getStreamTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderClient", True, "uncanonicalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newAssertQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newCall", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newDelete", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newInsert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "newUpdate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveExtrasBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveSelectionArgsBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation", False, "resolveValueBackReferences", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExceptionAllowed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExpectedCount", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtraBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withSelection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withSelectionBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValueBackReference", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withValues", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderOperation$Builder", False, "withYieldAllowed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Bundle)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.extras]", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Parcel)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Throwable)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.exception]", "value", "manual"] + - ["android.content", "ContentProviderResult", False, "ContentProviderResult", "(Uri)", "", "Argument[0]", "Argument[-1].Field[android.content.ContentProviderResult.uri]", "value", "manual"] + - ["android.content", "ContentResolver", True, "acquireContentProviderClient", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "acquireUnstableContentProviderClient", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "applyBatch", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "call", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "canonicalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "getStreamTypes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "getType", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "insert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "uncanonicalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentResolver", True, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "ContentValues", False, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.content", "ContentValues", False, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.content", "ContentValues", False, "putAll", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + # Currently only the Extras part of the intent and the data field are fully modeled + - ["android.content", "Intent", True, "Intent", "(Context,Class)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "Intent", "(Intent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", False, "Intent", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(String,Uri)", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", False, "Intent", "(String,Uri,Context,Class)", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "Intent", "(String,Uri,Context,Class)", "", "Argument[3]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "addCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "addFlags", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "createChooser", "", "", "Argument[0..2]", "ReturnValue.SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "getBundleExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getByteArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getCharSequenceExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getData", "", "", "Argument[-1].SyntheticField[android.content.Intent.data]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getDataString", "", "", "Argument[-1].SyntheticField[android.content.Intent.data]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "getExtras", "()", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "getIntent", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "getIntent", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", False, "getIntentOld", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "getIntentOld", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "getParcelableArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getParcelableArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getParcelableExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getSerializableExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringArrayExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringArrayListExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "getStringExtra", "(String)", "", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", False, "parseUri", "", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.data]", "taint", "manual"] + - ["android.content", "Intent", True, "parseUri", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putCharSequenceArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putIntegerArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putIntegerArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putParcelableArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "putStringArrayListExtra", "", "", "Argument[1]", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["android.content", "Intent", True, "replaceExtras", "(Intent)", "", "Argument[0].SyntheticField[android.content.Intent.extras].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["android.content", "Intent", True, "setAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClass", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClass", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setClassName", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setClassName", "(Context,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setClassName", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setComponent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setComponent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setData", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setData", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndNormalize", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndType", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndTypeAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setDataAndTypeAndNormalize", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.data]", "value", "manual"] + - ["android.content", "Intent", True, "setFlags", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setIdentifier", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setPackage", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setPackage", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.content", "Intent", True, "setType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "Intent", True, "setTypeAndNormalize", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "clear", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "putStringSet", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.content", "SharedPreferences$Editor", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/android.database.model.yml b/java/ql/lib/ext/android.database.model.yml new file mode 100644 index 00000000000..a7c6e6b1d9b --- /dev/null +++ b/java/ql/lib/ext/android.database.model.yml @@ -0,0 +1,27 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.database", "DatabaseUtils", False, "blobFileDescriptorForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "createDbFromSqlStatements", "(Context,String,int,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "longForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String)", "", "Argument[1..2]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String,String[])", "", "Argument[1..2]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "stringForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.database", "Cursor", True, "copyStringToBuffer", "", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["android.database", "Cursor", True, "getBlob", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getColumnName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getColumnNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getExtras", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getNotificationUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getNotificationUris", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "Cursor", True, "respond", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database", "DatabaseUtils", False, "appendSelectionArgs", "(String[],String[])", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["android.database", "DatabaseUtils", False, "concatenateWhere", "(String,String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.database.sqlite.model.yml b/java/ql/lib/ext/android.database.sqlite.model.yml new file mode 100644 index 00000000000..4b775715409 --- /dev/null +++ b/java/ql/lib/ext/android.database.sqlite.model.yml @@ -0,0 +1,89 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.database.sqlite", "SQLiteDatabase", False, "compileStatement", "(String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "delete", "(String,String,String[])", "", "Argument[0..1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execPerConnectionSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[0..2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[5..8]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[5..8]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[4]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[6..9]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[6..9]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[],CancellationSignal)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[0]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "insert", "(SQLiteDatabase,ContentValues)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4..7]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[-1]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendColumns", "(StringBuilder,String[])", "", "Argument[1].ArrayElement", "Argument[0]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendWhere", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "appendWhereStandalone", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String,String,String,String)", "", "Argument[1..5]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQuery", "(String[],String,String[],String,String,String,String)", "", "Argument[3..6]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildQueryString", "(boolean,String,String[],String,String,String,String,String)", "", "Argument[3..7]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionQuery", "(String[],String,String)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[2].Element", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String,String)", "", "Argument[4..7]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[2].Element", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[4..5]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "buildUnionSubQuery", "(String,String[],Set,int,String,String,String[],String,String)", "", "Argument[7..8]", "ReturnValue", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setProjectionMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setProjectionMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "setTables", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/android.net.model.yml b/java/ql/lib/ext/android.net.model.yml new file mode 100644 index 00000000000..2cda1efbc75 --- /dev/null +++ b/java/ql/lib/ext/android.net.model.yml @@ -0,0 +1,65 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.net", "Uri", True, "buildUpon", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "fromFile", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "fromParts", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getAuthority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedAuthority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getEncodedUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getHost", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getLastPathSegment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameter", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameterNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "getUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "normalizeScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "withAppendedPath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri", False, "writeToParcel", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendEncodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendEncodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "appendQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "appendQueryParameter", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "authority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "authority", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "clearQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedAuthority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedAuthority", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedFragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedFragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedOpaquePart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedOpaquePart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "encodedQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "encodedQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "opaquePart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "opaquePart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "path", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["android.net", "Uri$Builder", False, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["android.net", "Uri$Builder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.os.model.yml b/java/ql/lib/ext/android.os.model.yml new file mode 100644 index 00000000000..847ac6ce27b --- /dev/null +++ b/java/ql/lib/ext/android.os.model.yml @@ -0,0 +1,134 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["android.os", "Environment", False, "getExternalStorageDirectory", "()", "", "ReturnValue", "android-external-storage-dir", "manual"] + - ["android.os", "Environment", False, "getExternalStoragePublicDirectory", "(String)", "", "ReturnValue", "android-external-storage-dir", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.os", "BaseBundle", True, "get", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getString", "(String,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "getStringArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["android.os", "BaseBundle", True, "putAll", "(PersistableBundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putAll", "(PersistableBundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "putBoolean", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putBooleanArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putDouble", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putDoubleArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putInt", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putIntArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putLong", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putLongArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putString", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putString", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "BaseBundle", True, "putStringArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "BaseBundle", True, "putStringArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(PersistableBundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", False, "Bundle", "(PersistableBundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "clone", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + # Model for Bundle.deepCopy is not fully precise, as some map values aren't copied by value + - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "deepCopy", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "getBinder", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getBundle", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getByteArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String,CharSequence)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequence", "(String,CharSequence)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequenceArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getCharSequenceArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelable", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelableArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getParcelableArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getSerializable", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getSparseParcelableArray", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "getStringArrayList", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["android.os", "Bundle", True, "putAll", "(Bundle)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putAll", "(Bundle)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putBinder", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putBinder", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putBundle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putBundle", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putByte", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putByteArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putByteArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putChar", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequence", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequence", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putCharSequenceArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putFloat", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putFloatArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putIntegerArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelable", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelable", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putParcelableArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putSerializable", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSerializable", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putShort", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putShortArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSize", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSizeF", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSparseParcelableArray", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putSparseParcelableArray", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "putStringArrayList", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["android.os", "Bundle", True, "putStringArrayList", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["android.os", "Bundle", True, "readFromParcel", "", "", "Argument[0]", "Argument[-1].MapKey", "taint", "manual"] + - ["android.os", "Bundle", True, "readFromParcel", "", "", "Argument[0]", "Argument[-1].MapValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readArrayList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readBinderArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBinderList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readBooleanArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readBundle", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readByteArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readCharArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readDoubleArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readFileDescriptor", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readFloatArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readHashMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readIntArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readLongArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readMap", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelable", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readParcelableList", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["android.os", "Parcel", False, "readPersistableBundle", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSerializable", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSizeF", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSparseArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readSparseBooleanArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readStringArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readStringList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readStrongBinder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedArray", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedList", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["android.os", "Parcel", False, "readTypedObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["android.os", "Parcel", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/android.support.v4.app.model.yml b/java/ql/lib/ext/android.support.v4.app.model.yml new file mode 100644 index 00000000000..c99ebd9865e --- /dev/null +++ b/java/ql/lib/ext/android.support.v4.app.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["android.support.v4.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] diff --git a/java/ql/lib/ext/android.util.model.yml b/java/ql/lib/ext/android.util.model.yml new file mode 100644 index 00000000000..b57ff4819a7 --- /dev/null +++ b/java/ql/lib/ext/android.util.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["android.util", "AttributeSet", False, "getAttributeBooleanValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeCount", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeFloatValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeIntValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeListValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeName", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeNameResource", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeNamespace", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeResourceValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeUnsignedIntValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getAttributeValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getClassAttribute", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getIdAttribute", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getIdAttributeResourceValue", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getPositionDescription", "", "", "ReturnValue", "remote", "manual"] + - ["android.util", "AttributeSet", False, "getStyleAttribute", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["android.util", "Log", True, "d", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "e", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "i", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "v", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "w", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "wtf", "", "", "Argument[1]", "logging", "manual"] diff --git a/java/ql/lib/ext/android.webkit.model.yml b/java/ql/lib/ext/android.webkit.model.yml new file mode 100644 index 00000000000..05058493fe1 --- /dev/null +++ b/java/ql/lib/ext/android.webkit.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["android.webkit", "WebView", False, "getOriginalUrl", "()", "", "ReturnValue", "remote", "manual"] + - ["android.webkit", "WebView", False, "getUrl", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + # Models representing methods susceptible to XSS attacks. + - ["android.webkit", "WebView", False, "evaluateJavascript", "", "", "Argument[0]", "xss", "manual"] + - ["android.webkit", "WebView", False, "loadData", "", "", "Argument[0]", "xss", "manual"] + - ["android.webkit", "WebView", False, "loadDataWithBaseURL", "", "", "Argument[1]", "xss", "manual"] diff --git a/java/ql/lib/ext/android.widget.model.yml b/java/ql/lib/ext/android.widget.model.yml new file mode 100644 index 00000000000..1b6c94993e0 --- /dev/null +++ b/java/ql/lib/ext/android.widget.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["android.widget", "EditText", True, "getText", "", "", "ReturnValue", "android-widget", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["android.widget", "EditText", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/androidx.core.app.model.yml b/java/ql/lib/ext/androidx.core.app.model.yml new file mode 100644 index 00000000000..dbf8c0fb082 --- /dev/null +++ b/java/ql/lib/ext/androidx.core.app.model.yml @@ -0,0 +1,110 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["androidx.core.app", "AlarmManagerCompat", True, "setAlarmClock", "", "", "Argument[2..3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExact", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExactAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["androidx.core.app", "NotificationCompat$Action", True, "Action", "(IconCompat,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(IconCompat,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addRemoteInput", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setAllowGeneratedReplies", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setAuthenticationRequired", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setContextual", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Action$Builder", True, "setSemanticAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "bigLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "bigPicture", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "showBigPictureWhenCollapsed", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "bigText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "(Action)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[0].MapKey", "Argument[-1].SyntheticField[android.content.Intent.extras].MapKey", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "", "", "Argument[0].MapValue", "Argument[-1].SyntheticField[android.content.Intent.extras].MapValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "addPerson", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "build", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue.Field[android.app.Notification.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "extend", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "getExtras", "", "", "Argument[-1].SyntheticField[android.content.Intent.extras]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setActions", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setAutoCancel", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setBadgeIconType", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setBubbleMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCategory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setChannelId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setChronometerCountDown", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setColorized", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomBigContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomHeadsUpContentView", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDefaults", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDeleteIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setDeleteIntent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setExtras", "", "", "Argument[0]", "Argument[-1].SyntheticField[android.content.Intent.extras]", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setFlag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setForegroundServiceBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setFullScreenIntent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroup", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroupAlertBehavior", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setGroupSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLargeIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLights", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLocalOnly", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setLocusId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setNumber", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setOngoing", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setOnlyAlertOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setProgress", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPublicVersion", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setPublicVersion", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setRemoteInputHistory", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSettingsText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setShortcutId", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setShowWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSmallIcon", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSortKey", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSound", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setStyle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setSubText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setTicker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setTimeoutAfter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setUsesChronometer", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setVibrate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setVisibility", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$Builder", True, "setWhen", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "addLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setBigContentTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setSummaryText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/androidx.fragment.app.model.yml b/java/ql/lib/ext/androidx.fragment.app.model.yml new file mode 100644 index 00000000000..94c55a75c71 --- /dev/null +++ b/java/ql/lib/ext/androidx.fragment.app.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "add", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "attach", "(Fragment)", "", "Argument[0]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] + - ["androidx.fragment.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] diff --git a/java/ql/lib/ext/androidx.slice.builders.model.yml b/java/ql/lib/ext/androidx.slice.builders.model.yml new file mode 100644 index 00000000000..8b84e7ec341 --- /dev/null +++ b/java/ql/lib/ext/androidx.slice.builders.model.yml @@ -0,0 +1,93 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["androidx.slice.builders", "ListBuilder", True, "addAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addGridRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addGridRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addInputRange", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addInputRange", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRange", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRange", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRating", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRating", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addSelection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "addSelection", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "build", "", "", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "ReturnValue", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setAccentColor", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHeader", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHeader", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setHostExtras", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setIsError", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setKeywords", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreRow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder", True, "setSeeMoreRow", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setSummary", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$HeaderBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "addEndItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "addEndItem", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setInputAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setInputAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setMin", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setThumb", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$InputRangeBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setMode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RangeBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setInputAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setInputAction", "(PendingIntent)", "", "Argument[0]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setMax", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setMin", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RatingBuilder", True, "setValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "(SliceAction)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "addEndItem", "(SliceAction,boolean)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setEndOfSection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setLayoutDirection", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setPrimaryAction", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setPrimaryAction", "", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setSubtitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitle", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "(SliceAction)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "ListBuilder$RowBuilder", True, "setTitleItem", "(SliceAction,boolean)", "", "Argument[0].SyntheticField[androidx.slice.Slice.action]", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "create", "(PendingIntent,IconCompat,int,CharSequence)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "createDeeplink", "(PendingIntent,IconCompat,int,CharSequence)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "createToggle", "(PendingIntent,CharSequence,boolean)", "", "Argument[0]", "ReturnValue.SyntheticField[androidx.slice.Slice.action]", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "getAction", "", "", "Argument[-1].SyntheticField[androidx.slice.Slice.action]", "ReturnValue", "taint", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setChecked", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setContentDescription", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["androidx.slice.builders", "SliceAction", True, "setPriority", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/androidx.slice.model.yml b/java/ql/lib/ext/androidx.slice.model.yml new file mode 100644 index 00000000000..97481e886e5 --- /dev/null +++ b/java/ql/lib/ext/androidx.slice.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onMapIntentToUri", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onSlicePinned", "", "", "Parameter[0]", "contentprovider", "manual"] + - ["androidx.slice", "SliceProvider", True, "onSliceUnpinned", "", "", "Parameter[0]", "contentprovider", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "ReturnValue", "pending-intent-sent", "manual"] + - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "ReturnValue", "pending-intent-sent", "manual"] diff --git a/java/ql/lib/ext/cn.hutool.core.codec.model.yml b/java/ql/lib/ext/cn.hutool.core.codec.model.yml new file mode 100644 index 00000000000..8d583c144fb --- /dev/null +++ b/java/ql/lib/ext/cn.hutool.core.codec.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["cn.hutool.core.codec", "Base64", True, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml b/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml new file mode 100644 index 00000000000..b98da490aba --- /dev/null +++ b/java/ql/lib/ext/com.esotericsoftware.kryo.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.esotericsoftware.kryo.io", "Input", False, "Input", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml b/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml new file mode 100644 index 00000000000..78512602b9f --- /dev/null +++ b/java/ql/lib/ext/com.esotericsoftware.kryo5.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.esotericsoftware.kryo5.io", "Input", False, "Input", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml b/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml new file mode 100644 index 00000000000..640b96f769f --- /dev/null +++ b/java/ql/lib/ext/com.fasterxml.jackson.core.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.fasterxml.jackson.core", "JsonFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml new file mode 100644 index 00000000000..3768007ebe7 --- /dev/null +++ b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "convertValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue.Element", "ReturnValue", "taint", "manual"] + - ["com.fasterxml.jackson.databind", "ObjectReader", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.google.common.base.model.yml b/java/ql/lib/ext/com.google.common.base.model.yml new file mode 100644 index 00000000000..9d7e8491e81 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.base.model.yml @@ -0,0 +1,98 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.google.common.base", "Splitter", False, "onPattern", "(String)", "", "Argument[0]", "regex-use[]", "manual"] + - ["com.google.common.base", "Splitter", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToList", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["com.google.common.base", "Splitter$MapSplitter", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.google.common.base", "Ascii", False, "toLowerCase", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toLowerCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toUpperCase", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "toUpperCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "truncate", "(CharSequence,int,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Ascii", False, "truncate", "(CharSequence,int,String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "CaseFormat", True, "to", "(CaseFormat,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "apply", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "convert", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Converter", True, "convertAll", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Iterator)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object,Object,Object[])", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object,Object,Object[])", "", "Argument[3].ArrayElement", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(Appendable,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Iterator)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object,Object,Object[])", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object,Object,Object[])", "", "Argument[3].ArrayElement", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "appendTo", "(StringBuilder,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "join", "", "", "Argument[-1..2]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "on", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "skipNulls", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "useForNull", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "useForNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner", False, "withKeyValueSeparator", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "appendTo", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "appendTo", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterator)", "", "Argument[0].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Iterator)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "join", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "useForNull", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Joiner$MapJoiner", False, "useForNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects", False, "firstNonNull", "(Object,Object)", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects", False, "toStringHelper", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "(String,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "add", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "addValue", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "omitNullValues", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "MoreObjects$ToStringHelper", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Optional", True, "asSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "fromJavaUtil", "(Optional)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "fromNullable", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "get", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Optional)", "", "Argument[-1..0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Supplier)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "or", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Optional", True, "orNull", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Optional", True, "presentInstances", "(Iterable)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "toJavaUtil", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Optional", True, "toJavaUtil", "(Optional)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.base", "Preconditions", False, "checkNotNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Splitter", False, "split", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToList", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter", False, "splitToStream", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Splitter$MapSplitter", False, "split", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "emptyToNull", "(String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Strings", False, "lenientFormat", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "lenientFormat", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "nullToEmpty", "(String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.base", "Strings", False, "padEnd", "(String,int,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "padStart", "(String,int,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Strings", False, "repeat", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Supplier", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "memoize", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "memoizeWithExpiration", "(Supplier,long,TimeUnit)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "ofInstance", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Suppliers", False, "synchronizedSupplier", "(Supplier)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.base", "Verify", False, "verifyNotNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.cache.model.yml b/java/ql/lib/ext/com.google.common.cache.model.yml new file mode 100644 index 00000000000..f5c88464208 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.cache.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "asMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + # Lambda flow from Argument[1] not implemented + - ["com.google.common.cache", "Cache", True, "get", "(Object,Callable)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + # The true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modeled fully accurately. + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getAllPresent", "(Iterable)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "getIfPresent", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "Cache", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "apply", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getAll", "(Iterable)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.cache", "LoadingCache", True, "getUnchecked", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.collect.model.yml b/java/ql/lib/ext/com.google.common.collect.model.yml new file mode 100644 index 00000000000..b6c067fe5e0 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.collect.model.yml @@ -0,0 +1,560 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Methods depending on lambda flow are not currently modeled + # Methods depending on stronger aliasing properties than we support are also not modeled. + - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ArrayListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ArrayTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "forcePut", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "forcePut", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "inverse", "()", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "BiMap", True, "inverse", "()", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "getInstance", "(Class)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "putInstance", "(Class,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ClassToInstanceMap", True, "putInstance", "(Class,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "filter", "(Collection,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "orderedPermutations", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "orderedPermutations", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Collections2", False, "permutations", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "ConcurrentHashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "HashBasedTable", True, "create", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "HashBiMap", True, "create", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "HashBiMap", True, "create", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "HashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "HashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableBiMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "of", "(Class,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableClassToInstanceMap", True, "of", "(Class,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection", True, "asList", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "add", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "addAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableCollection$Builder", True, "build", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "of", "", "", "Argument[0..11]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "of", "", "", "Argument[12].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "reverse", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "sortedCopyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableList", True, "sortedCopyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableListMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "build", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "orderEntriesByValue", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMap$Builder", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "copyOf", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "inverse", "()", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "inverse", "()", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "build", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "orderKeysBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "orderValuesBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Iterable)", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Multimap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Multimap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Object[])", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultimap$Builder", True, "putAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "addCopies", "(Object,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "addCopies", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableMultiset$Builder", True, "setCount", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSet", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSetMultimap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable,Comparator)", "", "Argument[0].Element.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Iterable,Comparator)", "", "Argument[0].Element.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map,Comparator)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOf", "(Map,Comparator)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOfSorted", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "copyOfSorted", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMap", True, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Comparator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "copyOfSorted", "(SortedMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedMultiset", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Collection)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Comparator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOf", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "copyOfSorted", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "of", "", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableSortedSet", True, "of", "", "", "Argument[6].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "copyOf", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable", True, "of", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "build", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "orderColumnsBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "orderRowsBy", "(Comparator)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Cell)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "ImmutableTable$Builder", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable,Iterable)", "", "Argument[0..2].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0..3].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "concat", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "consumingIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "cycle", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "cycle", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "filter", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "filter", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "find", "(Iterable,Predicate,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "get", "(Iterable,int,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getLast", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "getOnlyElement", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "limit", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "mergeSorted", "(Iterable,Comparator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "paddedPartition", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "partition", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "skip", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "toArray", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "tryFind", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "unmodifiableIterable", "(ImmutableCollection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterables", False, "unmodifiableIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "asEnumeration", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator,Iterator)", "", "Argument[0..2].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator,Iterator,Iterator,Iterator)", "", "Argument[0..3].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "concat", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "consumingIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "cycle", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "cycle", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "filter", "(Iterator,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "filter", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "find", "(Iterator,Predicate,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "forArray", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "forEnumeration", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "get", "(Iterator,int,Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getLast", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getNext", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getNext", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator,Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "getOnlyElement", "(Iterator,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "limit", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "mergeSorted", "(Iterable,Comparator)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "paddedPartition", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "partition", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "peekingIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "peekingIterator", "(PeekingIterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "singletonIterator", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "toArray", "(Iterator,Class)", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "tryFind", "(Iterator,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "unmodifiableIterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Iterators", False, "unmodifiableIterator", "(UnmodifiableIterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "LinkedHashMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "LinkedListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "LinkedListMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object,Object[])", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object,Object[])", "", "Argument[2].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object[])", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "asList", "(Object,Object[])", "", "Argument[1].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "cartesianProduct", "(List)", "", "Argument[0].Element.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "cartesianProduct", "(List[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "charactersOf", "(CharSequence)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.collect", "Lists", False, "charactersOf", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newArrayList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newCopyOnWriteArrayList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "newLinkedList", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "partition", "(List,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Lists", False, "reverse", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.left]", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesDiffering", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.right]", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesInCommon", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnLeft", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnLeft", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnRight", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MapDifference", True, "entriesOnlyOnRight", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference$ValueDifference", True, "leftValue", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "MapDifference$ValueDifference", True, "rightValue", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(NavigableSet,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(Set,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "asMap", "(SortedSet,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(Map,Map,Equivalence)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[0].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[1].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "difference", "(SortedMap,Map)", "", "Argument[1].MapValue", "ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterEntries", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterKeys", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "filterValues", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "fromProperties", "(Properties)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "fromProperties", "(Properties)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEntry", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEntry", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "immutableEnumMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newEnumMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newHashMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newHashMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newLinkedHashMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newLinkedHashMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newTreeMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "newTreeMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "subMap", "(NavigableMap,Range)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "subMap", "(NavigableMap,Range)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedBiMap", "(BiMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedBiMap", "(BiMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "toMap", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "toMap", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(Map,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(NavigableMap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "transformValues", "(SortedMap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "uniqueIndex", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "uniqueIndex", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableBiMap", "(BiMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableBiMap", "(BiMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Maps", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "asMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "asMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "entries", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "entries", "()", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "keys", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Multimap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Multimap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "removeAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "replaceValues", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimap", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "asMap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterEntries", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterKeys", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(Multimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(Multimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(SetMultimap,Predicate)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "filterValues", "(SetMultimap,Predicate)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "forMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "forMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "index", "(Iterable,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "index", "(Iterator,Function)", "", "Argument[0].Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[0].MapKey", "Argument[1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[0].MapValue", "Argument[1].MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "invertFrom", "(Multimap,Multimap)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newListMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newListMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSetMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSetMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSortedSetMultimap", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "newSortedSetMultimap", "(Map,Supplier)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedListMultimap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedListMultimap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedMultimap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedMultimap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSetMultimap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSetMultimap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "synchronizedSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "transformValues", "(ListMultimap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "transformValues", "(Multimap,Function)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ImmutableListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ImmutableListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ListMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableListMultimap", "(ListMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(ImmutableMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(ImmutableMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableMultimap", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(ImmutableSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(ImmutableSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(SetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSetMultimap", "(SetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Multimaps", False, "unmodifiableSortedSetMultimap", "(SortedSetMultimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "add", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "elementSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "entrySet", "()", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "setCount", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset", True, "setCount", "(Object,int,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["com.google.common.collect", "Multiset$Entry", True, "getElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "copyHighestCountFirst", "(Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "difference", "(Multiset,Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "filter", "(Multiset,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "immutableEntry", "(Object,int)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "intersection", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "sum", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "union", "(Multiset,Multiset)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableMultiset", "(ImmutableMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableMultiset", "(Multiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Multisets", False, "unmodifiableSortedMultiset", "(SortedMultiset)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "MutableClassToInstanceMap", True, "create", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "MutableClassToInstanceMap", True, "create", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object,Object[])", "", "Argument[0]", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object,Object[])", "", "Argument[1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "ObjectArrays", False, "concat", "(Object[],Object[],Class)", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "drain", "(BlockingQueue,Collection,int,Duration)", "", "Argument[0].Element", "Argument[1].Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "drain", "(BlockingQueue,Collection,int,long,TimeUnit)", "", "Argument[0].Element", "Argument[1].Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newArrayDeque", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newConcurrentLinkedQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newLinkedBlockingDeque", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newLinkedBlockingQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newPriorityBlockingQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "newPriorityQueue", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "synchronizedDeque", "(Deque)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Queues", False, "synchronizedQueue", "(Queue)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "cartesianProduct", "(List)", "", "Argument[0].Element.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "cartesianProduct", "(Set[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "combinations", "(Set,int)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "difference", "(Set,Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(NavigableSet,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(Set,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "filter", "(SortedSet,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "intersection", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newConcurrentHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newCopyOnWriteArraySet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newHashSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newLinkedHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newSetFromMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "newTreeSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "powerSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "subSet", "(NavigableSet,Range)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "symmetricDifference", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "synchronizedNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "union", "(Set,Set)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets", False, "unmodifiableNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Sets$SetView", True, "copyInto", "(Set)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["com.google.common.collect", "Sets$SetView", True, "immutableCopy", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.Element.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "cellSet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.Element.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "column", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "column", "(Object)", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnKeySet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "columnMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "get", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "putAll", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Table", True, "remove", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "row", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "row", "(Object)", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowKeySet", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.MapValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "rowMap", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "Table", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getColumnKey", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getRowKey", "()", "", "Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Table$Cell", True, "getValue", "()", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "immutableCell", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapKey", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapValue.MapKey", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "newCustomTable", "(Map,Supplier)", "", "Argument[0].MapValue.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "synchronizedTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transformValues", "(Table,Function)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transformValues", "(Table,Function)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "transpose", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableRowSortedTable", "(RowSortedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "Tables", False, "unmodifiableTable", "(Table)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.columnKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey]", "value", "manual"] + - ["com.google.common.collect", "TreeBasedTable", True, "create", "(TreeBasedTable)", "", "Argument[0].SyntheticField[com.google.common.collect.Table.rowKey]", "ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey]", "value", "manual"] + - ["com.google.common.collect", "TreeMultimap", True, "create", "(Multimap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.common.collect", "TreeMultimap", True, "create", "(Multimap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.common.collect", "TreeMultiset", True, "create", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/com.google.common.flogger.model.yml b/java/ql/lib/ext/com.google.common.flogger.model.yml new file mode 100644 index 00000000000..b9a800b6210 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.flogger.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.google.common.flogger", "LoggingApi", True, "log", "", "", "Argument[0]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[])", "", "Argument[1..11]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,boolean)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,byte)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,char)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,double)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,float)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,int)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,long)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,short)", "", "Argument[1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,boolean,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,byte,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,char,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,double,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,float,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,int,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,long,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,short,Object)", "", "Argument[2]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "logVarargs", "", "", "Argument[0..1]", "logging", "manual"] diff --git a/java/ql/lib/ext/com.google.common.io.model.yml b/java/ql/lib/ext/com.google.common.io.model.yml new file mode 100644 index 00000000000..d08a5604338 --- /dev/null +++ b/java/ql/lib/ext/com.google.common.io.model.yml @@ -0,0 +1,88 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.google.common.io", "Resources", False, "asByteSource", "(URL)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "asCharSource", "(URL,Charset)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "copy", "(URL,OutputStream)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "readLines", "", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "toByteArray", "(URL)", "", "Argument[0]", "url-open-stream", "manual"] + - ["com.google.common.io", "Resources", False, "toString", "(URL,Charset)", "", "Argument[0]", "url-open-stream", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.google.common.io", "BaseEncoding", True, "decode", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decode", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingSource", "(CharSource)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingSource", "(CharSource)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingStream", "(Reader)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "decodingStream", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "encode", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "lowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "omitPadding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "upperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "withPadChar", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "BaseEncoding", True, "withSeparator", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "write", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeByte", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeBytes", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeChar", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeChars", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeDouble", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeFloat", "(float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeInt", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeLong", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeShort", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteArrayDataOutput", True, "writeUTF", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "asCharSource", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(ByteSource[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "concat", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "copyTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "openBufferedStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "openStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "slice", "(long,long)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteSource", True, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "copy", "(ReadableByteChannel,WritableByteChannel)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "limit", "(InputStream,long)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(ByteArrayInputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataInput", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "newDataOutput", "(ByteArrayOutputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "read", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "readFully", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "readFully", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "ByteStreams", False, "toByteArray", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "asByteSource", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(CharSource[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "concat", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "copyTo", "(Appendable)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "lines", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "openBufferedStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "openStream", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "readFirstLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "readLines", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharSource", True, "wrap", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "copy", "(Readable,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "readLines", "(Readable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "CharStreams", False, "toString", "(Readable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Closer", True, "register", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["com.google.common.io", "Files", False, "getFileExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Files", False, "getNameWithoutExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "Files", False, "simplifyPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "LineReader", False, "LineReader", "(Readable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["com.google.common.io", "LineReader", True, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "MoreFiles", False, "getFileExtension", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.common.io", "MoreFiles", False, "getNameWithoutExtension", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.hubspot.jinjava.model.yml b/java/ql/lib/ext/com.hubspot.jinjava.model.yml new file mode 100644 index 00000000000..2172da483f8 --- /dev/null +++ b/java/ql/lib/ext/com.hubspot.jinjava.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.hubspot.jinjava", "Jinjava", True, "render", "", "", "Argument[0]", "ssti", "manual"] + - ["com.hubspot.jinjava", "Jinjava", True, "renderForResult", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml new file mode 100644 index 00000000000..74b227da1dd --- /dev/null +++ b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getLiteralTemplate", "", "", "Argument[0]", "ssti", "manual"] + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getTemplate", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml b/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml new file mode 100644 index 00000000000..58b50652f1b --- /dev/null +++ b/java/ql/lib/ext/com.opensymphony.xwork2.ognl.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "callMethod", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["com.opensymphony.xwork2.ognl", "OgnlUtil", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml b/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml new file mode 100644 index 00000000000..9f0e9906e79 --- /dev/null +++ b/java/ql/lib/ext/com.rabbitmq.client.impl.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["com.rabbitmq.client.impl", "Frame", True, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client.impl", "Frame", True, "getPayload", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client.impl", "FrameHandler", True, "readFrame", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.rabbitmq.client.impl", "Frame", False, "fromBodyFragment", "(int,byte[],int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client.impl", "Frame", False, "readFrom", "(DataInputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client.impl", "Frame", True, "writeTo", "(DataOutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/com.rabbitmq.client.model.yml b/java/ql/lib/ext/com.rabbitmq.client.model.yml new file mode 100644 index 00000000000..ec313e8ef74 --- /dev/null +++ b/java/ql/lib/ext/com.rabbitmq.client.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["com.rabbitmq.client", "Command", True, "getContentBody", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "Command", True, "getContentHeader", "()", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "Consumer", True, "handleDelivery", "(String,Envelope,BasicProperties,byte[])", "", "Parameter[3]", "remote", "manual"] + - ["com.rabbitmq.client", "QueueingConsumer", True, "nextDelivery", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "doCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "mapCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "primitiveCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "responseCall", "", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcClient", True, "stringCall", "(String)", "", "ReturnValue", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(BasicProperties,byte[],BasicProperties)", "", "Parameter[1]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(Delivery,BasicProperties)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCall", "(byte[],BasicProperties)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(BasicProperties,byte[])", "", "Parameter[1]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(Delivery)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "handleCast", "(byte[])", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "postprocessReplyProperties", "(Delivery,Builder)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "RpcServer", True, "preprocessReplyProperties", "(Delivery,Builder)", "", "Parameter[0]", "remote", "manual"] + - ["com.rabbitmq.client", "StringRpcServer", True, "handleStringCall", "", "", "Parameter[0]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.rabbitmq.client", "GetResponse", True, "GetResponse", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["com.rabbitmq.client", "GetResponse", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client", "QueueingConsumer$Delivery", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["com.rabbitmq.client", "RpcClient$Response", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml new file mode 100644 index 00000000000..57753bc31d0 --- /dev/null +++ b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "asyncSearch", "", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..7]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..7]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,Filter,String[])", "", "Argument[0..3]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,String,String[])", "", "Argument[0..3]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..6]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..6]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[])", "", "Argument[0..5]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,String,String[])", "", "Argument[0..5]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] diff --git a/java/ql/lib/ext/com.zaxxer.hikari.model.yml b/java/ql/lib/ext/com.zaxxer.hikari.model.yml new file mode 100644 index 00000000000..5fcab32cc7e --- /dev/null +++ b/java/ql/lib/ext/com.zaxxer.hikari.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.zaxxer.hikari", "HikariConfig", False, "HikariConfig", "(Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["com.zaxxer.hikari", "HikariConfig", False, "setJdbcUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/dummy.model.yml b/java/ql/lib/ext/dummy.model.yml new file mode 100644 index 00000000000..0269fe72311 --- /dev/null +++ b/java/ql/lib/ext/dummy.model.yml @@ -0,0 +1,18 @@ +extensions: + # Make sure that the extensible model predicates are at least defined as empty. + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: [] \ No newline at end of file diff --git a/java/ql/lib/ext/experimental/android.webkit.model.yml b/java/ql/lib/ext/experimental/android.webkit.model.yml new file mode 100644 index 00000000000..ce70ae7e87b --- /dev/null +++ b/java/ql/lib/ext/experimental/android.webkit.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["android.webkit", "WebResourceRequest", False, "getUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "android-web-resource-response"] diff --git a/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml b/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml new file mode 100644 index 00000000000..6032a9c8a18 --- /dev/null +++ b/java/ql/lib/ext/experimental/com.auth0.jwt.interfaces.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptExpiresAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptIssuedAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptLeeway", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "acceptNotBefore", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "ignoreIssuedAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withAnyOfAudience", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withArrayClaim", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withAudience", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withClaim", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withClaimPresence", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withIssuer", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withJWTId", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] + - ["com.auth0.jwt.interfaces", "Verification", True, "withSubject", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "hardcoded-jwt-key"] diff --git a/java/ql/lib/ext/experimental/com.jfinal.core.model.yml b/java/ql/lib/ext/experimental/com.jfinal.core.model.yml new file mode 100644 index 00000000000..b6c7cc438f5 --- /dev/null +++ b/java/ql/lib/ext/experimental/com.jfinal.core.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSourceModel + data: + - ["com.jfinal.core", "Controller", True, "get", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getBoolean", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookie", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieObject", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieObjects", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getCookieToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getDate", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getFile", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getFiles", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getHeader", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getKv", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getPara", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaMap", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToBoolean", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToDate", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValues", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValuesToInt", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] + - ["com.jfinal.core", "Controller", True, "getParaValuesToLong", "", "", "ReturnValue", "remote", "manual", "file-path-injection"] diff --git a/java/ql/lib/ext/experimental/dummy.model.yml b/java/ql/lib/ext/experimental/dummy.model.yml new file mode 100644 index 00000000000..b43cb611b66 --- /dev/null +++ b/java/ql/lib/ext/experimental/dummy.model.yml @@ -0,0 +1,15 @@ +# Define the extensible prediactes related to experimental queries +# to at least be empty. +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSourceModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: experimentalSinkModel + data: [] + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: [] diff --git a/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml b/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml new file mode 100644 index 00000000000..12267dcd845 --- /dev/null +++ b/java/ql/lib/ext/experimental/io.undertow.server.handlers.resource.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["io.undertow.server.handlers.resource", "Resource", True, "getFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["io.undertow.server.handlers.resource", "Resource", True, "getFilePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["io.undertow.server.handlers.resource", "Resource", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml b/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml new file mode 100644 index 00000000000..9500beba15b --- /dev/null +++ b/java/ql/lib/ext/experimental/jakarta.servlet.http.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSourceModel + data: + - ["jakarta.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/java.io.model.yml b/java/ql/lib/ext/experimental/java.io.model.yml new file mode 100644 index 00000000000..8d6d98ff47d --- /dev/null +++ b/java/ql/lib/ext/experimental/java.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["java.io", "FileInputStream", True, "FileInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual", "android-web-resource-response"] diff --git a/java/ql/lib/ext/experimental/java.lang.model.yml b/java/ql/lib/ext/experimental/java.lang.model.yml new file mode 100644 index 00000000000..696a0d9aba3 --- /dev/null +++ b/java/ql/lib/ext/experimental/java.lang.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSinkModel + data: + - ["java.lang", "Thread", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "thread-resource-abuse"] + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["java.lang", "Math", False, "max", "", "", "Argument[0..1]", "ReturnValue", "value", "manual", "thread-resource-abuse"] + - ["java.lang", "Math", False, "min", "", "", "Argument[0..1]", "ReturnValue", "value", "manual", "thread-resource-abuse"] diff --git a/java/ql/lib/ext/experimental/java.nio.file.model.yml b/java/ql/lib/ext/experimental/java.nio.file.model.yml new file mode 100644 index 00000000000..d1d0d8d3d6e --- /dev/null +++ b/java/ql/lib/ext/experimental/java.nio.file.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Path", True, "resolve", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Path", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/java.util.concurrent.model.yml b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml new file mode 100644 index 00000000000..82ff0a00570 --- /dev/null +++ b/java/ql/lib/ext/experimental/java.util.concurrent.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSinkModel + data: + - ["java.util.concurrent", "TimeUnit", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "thread-resource-abuse"] + - ["java.util.concurrent", "TimeUnit", True, "sleep", "", "", "Argument[0]", "thread-pause", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/experimental/javax.servlet.http.model.yml b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml new file mode 100644 index 00000000000..db140149a99 --- /dev/null +++ b/java/ql/lib/ext/experimental/javax.servlet.http.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSourceModel + data: + - ["javax.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual", "unsafe-url-forward"] + - addsTo: + pack: codeql/java-all + extensible: experimentalSourceModel + data: + - ["javax.servlet.http", "HttpServletRequest", False, "getPathInfo", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getPathTranslated", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURI", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURL", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + - ["javax.servlet.http", "HttpServletRequest", False, "getServletPath", "()", "", "ReturnValue", "uri-path", "manual", "permissive-dot-regex-query"] + diff --git a/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml b/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml new file mode 100644 index 00000000000..71839d3abbe --- /dev/null +++ b/java/ql/lib/ext/experimental/org.apache.logging.log4j.message.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["org.apache.logging.log4j.message", "MapMessage", True, "put", "", "", "Argument[1]", "Argument[-1]", "taint", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "putAll", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "with", "", "", "Argument[-1]", "ReturnValue", "value", "manual", "log4j-injection"] + - ["org.apache.logging.log4j.message", "MapMessage", True, "with", "", "", "Argument[1]", "Argument[-1]", "taint", "manual", "log4j-injection"] diff --git a/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml b/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml new file mode 100644 index 00000000000..5b196c272fb --- /dev/null +++ b/java/ql/lib/ext/experimental/org.apache.logging.log4j.model.yml @@ -0,0 +1,362 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSinkModel + data: + - ["org.apache.logging.log4j", "CloseableThreadContext", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext$Instance", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "CloseableThreadContext$Instance", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "put", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "putAll", "", "", "Argument[0]", "log4j", "manual", "log4j-injection"] + - ["org.apache.logging.log4j", "ThreadContext", False, "putIfNull", "", "", "Argument[1]", "log4j", "manual", "log4j-injection"] diff --git a/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml b/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml new file mode 100644 index 00000000000..1d4d808cdcd --- /dev/null +++ b/java/ql/lib/ext/experimental/org.springframework.core.io.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: experimentalSinkModel + data: + - ["org.springframework.core.io", "ClassPathResource", True, "getFilename", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "getPath", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "getURL", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ClassPathResource", True, "resolveURL", "", "", "Argument[-1]", "get-resource", "manual", "unsafe-url-forward"] + - addsTo: + pack: codeql/java-all + extensible: experimentalSummaryModel + data: + - ["org.springframework.core.io", "ClassPathResource", False, "ClassPathResource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "Resource", True, "createRelative", "", "", "Argument[0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] + - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "", "", "Argument[0]", "ReturnValue", "taint", "manual", "unsafe-url-forward"] diff --git a/java/ql/lib/ext/flexjson.model.yml b/java/ql/lib/ext/flexjson.model.yml new file mode 100644 index 00000000000..59249214262 --- /dev/null +++ b/java/ql/lib/ext/flexjson.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["flexjson", "JSONDeserializer", True, "use", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/freemarker.cache.model.yml b/java/ql/lib/ext/freemarker.cache.model.yml new file mode 100644 index 00000000000..b65e6386ad6 --- /dev/null +++ b/java/ql/lib/ext/freemarker.cache.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["freemarker.cache", "StringTemplateLoader", True, "putTemplate", "", "", "Argument[1]", "ssti", "manual"] diff --git a/java/ql/lib/ext/freemarker.template.model.yml b/java/ql/lib/ext/freemarker.template.model.yml new file mode 100644 index 00000000000..96087a2b9ba --- /dev/null +++ b/java/ql/lib/ext/freemarker.template.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["freemarker.template", "Template", True, "Template", "(String,Reader)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration,String)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Configuration)", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration)", "", "Argument[2]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,ParserConfiguration,String)", "", "Argument[2]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,String)", "", "Argument[2]", "ssti", "manual"] diff --git a/java/ql/lib/ext/generated/kotlinstdlib.model.yml b/java/ql/lib/ext/generated/kotlinstdlib.model.yml new file mode 100644 index 00000000000..be3ee65d162 --- /dev/null +++ b/java/ql/lib/ext/generated/kotlinstdlib.model.yml @@ -0,0 +1,6473 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models in the Kotlin StdLib @30ce58cea74 framework. + +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["kotlin.io", "FilesKt", false, "appendBytes", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "appendText", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "bufferedWriter", "(File,Charset,int)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "copyRecursively", "(File,File,boolean,Function2)", "", "Argument[1]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "outputStream", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "printWriter", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writeBytes", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writeText", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "FilesKt", false, "writer", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readBytes", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readText", "(URL,Charset)", "", "Argument[0]", "open-url", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["kotlin.collections", "AbstractCollection", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "ArrayDeque", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "addFirst", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "addLast", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "first", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "firstOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "last", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "lastOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeFirstOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeLast", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArrayDeque", false, "removeLastOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "asList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(Object[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(boolean[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(byte[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(char[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(double[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(float[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(int[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(long[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateByTo", "(short[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "associateWithTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[0].ArrayElement", "Argument[1].ArrayElement", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(Object[],Object[],int,int,int)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(byte[],byte[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyInto", "(char[],char[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOf", "(char[],int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(Object[],int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "copyOfRangeInline", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "drop", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "dropLast", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "dropLastWhile", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fill", "(Object[],Object,int,int)", "", "Argument[1]", "Argument[0].ArrayElement", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIndexedTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIsInstanceTo", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterIsInstanceTo", "(Object[],Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotNullTo", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterNotTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "filterTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "findLast", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "first", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "firstOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedIterableTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapIndexedSequenceTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapSequenceTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "flatMapTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "fold", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRight", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "foldRightIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(Object[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(Object[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(boolean[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(boolean[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(byte[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(byte[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(char[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(char[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(double[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(double[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(float[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(float[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(int[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(int[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(long[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(long[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(short[],Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "groupByTo", "(short[],Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "ifEmpty", "(Object[],Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinTo", "(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "joinToString", "(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "last", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "last", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "lastOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "lastOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedNotNullTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(Object[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(boolean[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(byte[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(char[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(double[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(float[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(int[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(long[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapIndexedTo", "(short[],Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapNotNullTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(Object[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(boolean[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(byte[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(char[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(double[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(float[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(int[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(long[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "mapTo", "(short[],Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "max", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxByOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxByOrThrow", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOfWith", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOfWithOrNull", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOrNull", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxOrThrow", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWithOrNull", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "maxWithOrThrow", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "min", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minByOrNull", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minByOrThrow", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOfWith", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOfWithOrNull", "(Object[],Comparator,Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOrNull", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minOrThrow", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWithOrNull", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "minWithOrThrow", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(byte[],Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEach", "(char[],Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(byte[],Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "onEachIndexed", "(char[],Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "orEmpty", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Collection)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(Object[],Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(byte[],byte[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plus", "(char[],char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "plusElement", "(Object[],Object)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduce", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceIndexed", "(Object[],Function3)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceIndexedOrNull", "(Object[],Function3)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reduceOrNull", "(Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "requireNoNulls", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversed", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "reversedArray", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFold", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "runningFoldIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(Object[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(boolean[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(byte[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(char[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(double[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(float[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(int[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(long[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scan", "(short[],Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(Object[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(boolean[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(byte[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(char[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(double[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(float[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(int[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(long[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "scanIndexed", "(short[],Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "single", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "singleOrNull", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "slice", "(Object[],IntRange)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(Object[],Collection)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(Object[],IntRange)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(byte[],IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sliceArray", "(char[],IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sorted", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArray", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayDescending", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedArrayWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedBy", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedByDescending", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedDescending", "(Comparable[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "sortedWith", "(Object[],Comparator)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "take", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "takeLast", "(Object[],int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "takeLastWhile", "(Object[],Function1)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(Object[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(boolean[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(byte[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(char[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(double[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(float[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(int[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(long[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toCollection", "(short[],Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toMutableList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toString", "(byte[],Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "toTypedArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(Object[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(byte[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "union", "(char[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable,Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Iterable,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[],Function2)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "ArraysKt", false, "zip", "(Object[],Object[],Function2)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "addAll", "(Collection,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "arrayListOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asIterable", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asReversed", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "asReversedMutable", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associate", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateBy", "(Iterable,Function1,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWith", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "associateWithTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component1", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component2", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component3", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component4", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "component5", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "distinct", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "distinctBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "drop", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropLast", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropLastWhile", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "dropWhile", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAt", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAt", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrElse", "(Iterable,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrElse", "(List,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrNull", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "elementAtOrNull", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "fill", "(List,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filter", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIndexedTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstance", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstance", "(Iterable,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterIsInstanceTo", "(Iterable,Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNot", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotNullTo", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterNotTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "filterTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "find", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "findLast", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "findLast", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "first", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstNotNullOf", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstNotNullOfOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "firstOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapIndexedIterableTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapIndexedSequenceTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapSequenceTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatMapTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "flatten", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "fold", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldRight", "(List,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "foldRightIndexed", "(List,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "getOrElse", "(List,int,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "getOrNull", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "groupByTo", "(Iterable,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "groupByTo", "(Iterable,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "ifEmpty", "(Collection,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "intersect", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "iterator", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinTo", "(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "joinToString", "(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "last", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "lastOrNull", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "listOfNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "map", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapIndexedNotNullTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapIndexedTo", "(Iterable,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapNotNullTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mapTo", "(Iterable,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "max", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxByOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxByOrThrow", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOfWith", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOfWithOrNull", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxOrThrow", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWithOrNull", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "maxWithOrThrow", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "min", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minByOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minByOrThrow", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOfWith", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOfWithOrNull", "(Iterable,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minOrThrow", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWithOrNull", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minWithOrThrow", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minus", "(Iterable,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "minusElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "mutableListOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "onEach", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "onEachIndexed", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "orEmpty", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "orEmpty", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "partition", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Collection,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plus", "(Iterable,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusAssign", "(Collection,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Collection,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Collection,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Iterable,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "plusElement", "(Iterable,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "random", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "random", "(Collection,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "randomOrNull", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "randomOrNull", "(Collection,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduce", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceIndexed", "(Iterable,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceIndexedOrNull", "(Iterable,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceOrNull", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRight", "(List,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightIndexed", "(List,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightIndexedOrNull", "(List,Function3)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reduceRightOrNull", "(List,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "remove", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeFirst", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeFirstOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeLast", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "removeLastOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "requireNoNulls", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "requireNoNulls", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "reversed", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "runningFold", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "runningFoldIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "scan", "(Iterable,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "scanIndexed", "(Iterable,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "shuffled", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "shuffled", "(Iterable,Random)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "single", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "singleOrNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "slice", "(List,IntRange)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "slice", "(List,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sorted", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedBy", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedByDescending", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedDescending", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "sortedWith", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "subtract", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "take", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeLast", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeLastWhile", "(List,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "takeWhile", "(Iterable,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toCollection", "(Iterable,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toHashSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toList", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableList", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableList", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toMutableSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSortedSet", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "toSortedSet", "(Iterable,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "union", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "union", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "unzip", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "withIndex", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Iterable,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[],Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zip", "(Iterable,Object[],Function2)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zipWithNext", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "CollectionsKt", false, "zipWithNext", "(Iterable,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "aggregateTo", "(Grouping,Map,Function4)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "eachCountTo", "(Grouping,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "foldTo", "(Grouping,Map,Function2,Function3)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "foldTo", "(Grouping,Map,Object,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "GroupingKt", false, "reduceTo", "(Grouping,Map,Function3)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "IndexedValue", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "copy", "(int,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "IndexedValue", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "getValue", "(Map,Object,KProperty)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "getVar", "(Map,Object,KProperty)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "setValue", "(Map,Object,KProperty,Object)", "", "Argument[2]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapAccessorsKt", false, "setValue", "(Map,Object,KProperty,Object)", "", "Argument[3]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "asIterable", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "component1", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "component2", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filter", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterKeys", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNot", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterNotTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "filterValues", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "firstNotNullOf", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "firstNotNullOfOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "flatMapSequenceTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "flatMapTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "get", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrElse", "(Map,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(ConcurrentMap,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(Map,Object,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getOrPut", "(Map,Object,Function0)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "getValue", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "ifEmpty", "(Map,Function0)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "iterator", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "map", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeys", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapKeysTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapNotNullTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapOf", "(Pair)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapTo", "(Map,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValues", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mapValuesTo", "(Map,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxBy", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxByOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxByOrThrow", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxOfWith", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxOfWithOrNull", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWith", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWithOrNull", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "maxWithOrThrow", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minBy", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minByOrNull", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minByOrThrow", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minOfWith", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minOfWithOrNull", "(Map,Comparator,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWith", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWithOrNull", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minWithOrThrow", "(Map,Comparator)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "minus", "(Map,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "mutableIterator", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "onEach", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "onEachIndexed", "(Map,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "orEmpty", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Pair[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plus", "(Map,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Map)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Pair)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "plusAssign", "(Map,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "putAll", "(Map,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "putAll", "(Map,Sequence)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "remove", "(Map,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "set", "(Map,Object,Object)", "", "Argument[1]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "set", "(Map,Object,Object)", "", "Argument[2]", "Argument[0].Element", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toList", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Iterable,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Map,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Pair[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Pair[],Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMap", "(Sequence,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toMutableMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toPair", "(Entry)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "toSortedMap", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefault", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefault", "(Map,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefaultMutable", "(Map,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "MapsKt", false, "withDefaultMutable", "(Map,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minus", "(Set,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "minusElement", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "orEmpty", "(Set)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Sequence)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plus", "(Set,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plusElement", "(Set,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "plusElement", "(Set,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOf", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "SetsKt", false, "setOfNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "asByteArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "asUByteArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UByteArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UIntArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(ULongArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "associateWithTo", "(UShortArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "contentToString", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[0].Element", "Argument[1].Element", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UByteArray,UByteArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UIntArray,UIntArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(ULongArray,ULongArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyInto", "(UShortArray,UShortArray,int,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOf", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOf", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "copyOfRange", "(UByteArray,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "drop", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLast", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "dropLastWhile", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterNotTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "filterTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "flatMapTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "fold", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRight", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "foldRightIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UByteArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UByteArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UIntArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UIntArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(ULongArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(ULongArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UShortArray,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "groupByTo", "(UShortArray,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UByteArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UIntArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(ULongArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapIndexedTo", "(UShortArray,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UByteArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UIntArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(ULongArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "mapTo", "(UShortArray,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEach", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UByteArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UIntArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(ULongArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "onEachIndexed", "(UShortArray,Function2)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,UByteArray)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "plus", "(UByteArray,byte)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversed", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "reversedArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFold", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "runningFoldIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UByteArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UIntArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(ULongArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scan", "(UShortArray,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UByteArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UIntArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(ULongArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "scanIndexed", "(UShortArray,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sliceArray", "(UByteArray,IntRange)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArray", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedArrayDescending", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "sortedDescending", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "take", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UByteArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UIntArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(ULongArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLast", "(UShortArray,int)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UByteArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UIntArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(ULongArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "takeLastWhile", "(UShortArray,Function1)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "toByteArray", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.collections", "UArraysKt", false, "toUByteArray", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Comparable,Comparable[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object,Object,Comparator)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "maxOf", "(Object,Object[],Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Comparable,Comparable[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object,Object,Comparator)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "minOf", "(Object,Object[],Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", false, "reversed", "(Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextElement", true, "AbstractCoroutineContextElement", "(Key)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextKey", true, "AbstractCoroutineContextKey", "(Key,Function1)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "AbstractCoroutineContextKey", true, "AbstractCoroutineContextKey", "(Key,Function1)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "fold", "(Object,Function2)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "fold", "(Object,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "get", "(Key)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "minusKey", "(Key)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "minusKey", "(Key)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "plus", "(CoroutineContext)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext", true, "plus", "(CoroutineContext)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContext$Element", true, "getKey", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContextImplKt", false, "getPolymorphicElement", "(Element,Key)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines", "CoroutineContextImplKt", false, "minusPolymorphicKey", "(Element,Key)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", false, "intercepted", "(Continuation)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", true, "getCallerFrame", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "AccessDeniedException", false, "AccessDeniedException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "buffered", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "buffered", "(OutputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "bufferedReader", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "byteInputStream", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "copyTo", "(InputStream,OutputStream,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "inputStream", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "inputStream", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "readBytes", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "readBytes", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "ByteStreamsKt", false, "reader", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "CloseableKt", false, "use", "(Closeable,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileAlreadyExistsException", false, "FileAlreadyExistsException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "FileSystemException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getOther", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileSystemException", true, "getReason", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "maxDepth", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onEnter", "(Function1)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onEnter", "(Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onFail", "(Function2)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onFail", "(Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onLeave", "(Function1)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FileTreeWalk", false, "onLeave", "(Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "relativeToOrSelf", "(File,File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolve", "(File,File)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolve", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolveSibling", "(File,File)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "resolveSibling", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walk", "(File,FileWalkDirection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walkBottomUp", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "FilesKt", false, "walkTopDown", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "NoSuchFileException", false, "NoSuchFileException", "(File,File,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "buffered", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "buffered", "(Writer,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "copyTo", "(Reader,Writer,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "forEachLine", "(Reader,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "lineSequence", "(BufferedReader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "readText", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "reader", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.io", "TextStreamsKt", false, "useLines", "(Reader,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", true, "AdaptedFunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorKt", false, "iterator", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", false, "iterator", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", false, "iterator", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", false, "toArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "compute", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "getBoundReceiver", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CallableReference", true, "getSignature", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", false, "toArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", false, "getClassQualifiedName", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", false, "getClassSimpleName", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CollectionToArray", false, "toArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "CollectionToArray", false, "toArray", "(Collection,Object[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "FunctionReference", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,KDeclarationContainer,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "FunctionReferenceImpl", true, "FunctionReferenceImpl", "(int,Object,Class,String,String,int)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", true, "stringPlus", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", true, "stringPlus", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", true, "MutablePropertyReference", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", true, "MutablePropertyReference0", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0Impl", true, "MutablePropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", true, "MutablePropertyReference1", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1Impl", true, "MutablePropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", true, "MutablePropertyReference2", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", true, "MutablePropertyReference2", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2Impl", true, "MutablePropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PackageReference", false, "PackageReference", "(Class,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PrimitiveSpreadBuilder", true, "addSpread", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "PropertyReference", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", true, "PropertyReference0", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0Impl", true, "PropertyReference0Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", true, "PropertyReference1", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1Impl", true, "PropertyReference1Impl", "(Object,Class,String,String,int)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", true, "PropertyReference2", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", true, "PropertyReference2", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(Class,String,String,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(Class,String,String,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2Impl", true, "PropertyReference2Impl", "(KDeclarationContainer,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "function", "(FunctionReference)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "getOrCreateKotlinPackage", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableCollectionType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty0", "(MutablePropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty1", "(MutablePropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "mutableProperty2", "(MutablePropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nothingType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "nullableTypeOf", "(KClassifier)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "platformType", "(KType,KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "platformType", "(KType,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property0", "(PropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property1", "(PropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "property2", "(PropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "setUpperBounds", "(KTypeParameter,KType)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(Class,KTypeProjection,KTypeProjection)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeOf", "(KClassifier)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "Reflection", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "function", "(FunctionReference)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "getOrCreateKotlinPackage", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableCollectionType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty0", "(MutablePropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty1", "(MutablePropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "mutableProperty2", "(MutablePropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "nothingType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "platformType", "(KType,KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "platformType", "(KType,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property0", "(PropertyReference0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property1", "(PropertyReference1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "property2", "(PropertyReference2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "setUpperBounds", "(KTypeParameter,List)", "", "Argument[1].Element", "Argument[0]", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeOf", "(KClassifier,List,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeOf", "(KClassifier,List,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", true, "typeParameter", "(Object,String,KVariance,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "add", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "addSpread", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "toArray", "(Object[])", "", "Argument[-1]", "Argument[0].ArrayElement", "taint", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", true, "toArray", "(Object[])", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableCollection", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableCollection", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterable", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterable", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableIterator", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableList", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableList", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableListIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableListIterator", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMap", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMap", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMapEntry", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableMapEntry", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableSet", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "asMutableSet", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "beforeCheckcastToFunctionOfArity", "(Object,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "beforeCheckcastToFunctionOfArity", "(Object,int,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToCollection", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToIterable", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToList", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToListIterator", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToMap", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToMapEntry", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", true, "castToSet", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "TypeParameterReference", "(Object,String,KVariance,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "TypeParameterReference", "(Object,String,KVariance,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", false, "setUpperBounds", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,KType,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "TypeReference", "(KClassifier,List,boolean)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.jvm.internal", "TypeReference", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.properties", "ObservableProperty", true, "ObservableProperty", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.random", "PlatformRandomKt", false, "asJavaRandom", "(Random)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "PlatformRandomKt", false, "asKotlinRandom", "(Random)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "Random", true, "nextBytes", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "Random", true, "nextBytes", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "URandomKt", false, "nextUBytes", "(Random,UByteArray)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.random", "URandomKt", false, "nextUBytes", "(Random,UByteArray,int,int)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "CharRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "IntRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "LongRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtLeast", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtLeast", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtMost", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceAtMost", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,ClosedFloatingPointRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,ClosedRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "coerceIn", "(Comparable,Comparable,Comparable)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeTo", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeTo", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeUntil", "(Comparable,Comparable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "RangesKt", false, "rangeUntil", "(Comparable,Comparable)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "UIntRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.ranges", "ULongRange$Companion", false, "getEMPTY", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KClasses", false, "cast", "(KClass,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KClasses", false, "safeCast", "(KClass,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KType", true, "getArguments", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KType", true, "getClassifier", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeParameter", true, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeParameter", true, "getUpperBounds", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "KTypeProjection", "(KVariance,KType)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "contravariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "copy", "(KVariance,KType)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "covariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "getType", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "invariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "contravariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "covariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", false, "invariant", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "TypesJVMKt", false, "getJavaType", "(KType)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.reflect", "WildcardTypeImpl$Companion", false, "getSTAR", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequenceScope", true, "yieldAll", "(Sequence)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "asSequence", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateByTo", "(Sequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWith", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "associateWithTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "chunked", "(Sequence,int,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "constrainOnce", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinct", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinctBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "distinctBy", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "drop", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "dropWhile", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "dropWhile", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAt", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAtOrElse", "(Sequence,int,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "elementAtOrNull", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filter", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filter", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIndexedTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstance", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstance", "(Sequence,Class)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterIsInstanceTo", "(Sequence,Collection,Class)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNot", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNot", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotNullTo", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterNotTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "filterTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "find", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "findLast", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "first", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "first", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstNotNullOf", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstNotNullOfOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "firstOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMap", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMap", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIndexedIterableTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIndexedSequenceTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterable", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterable", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapIterableTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatMapTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flatten", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "flattenSequenceOfIterable", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "fold", "(Sequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "foldIndexed", "(Sequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Function0,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "generateSequence", "(Object,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "groupByTo", "(Sequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "groupByTo", "(Sequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "Argument[1]", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinTo", "(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[6]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "joinToString", "(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1)", "", "Argument[5]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "last", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "last", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "lastOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "lastOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "map", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "map", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexed", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexed", "(Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNull", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNull", "(Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedNotNullTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapIndexedTo", "(Sequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNull", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapNotNullTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "mapTo", "(Sequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "max", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxByOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxByOrThrow", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOfWith", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOfWithOrNull", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxOrThrow", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWith", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWithOrNull", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "maxWithOrThrow", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "min", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minBy", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minByOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minByOrThrow", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOfWith", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOfWithOrNull", "(Sequence,Comparator,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minOrThrow", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWith", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWithOrNull", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minWithOrThrow", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "minus", "(Sequence,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "onEach", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "onEachIndexed", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "orEmpty", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "partition", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduce", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceIndexed", "(Sequence,Function3)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceIndexedOrNull", "(Sequence,Function3)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "reduceOrNull", "(Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "requireNoNulls", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "single", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "single", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "singleOrNull", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "singleOrNull", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "take", "(Sequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "takeWhile", "(Sequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "takeWhile", "(Sequence,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[0]", "Argument[1].Element", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toCollection", "(Sequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toHashSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toList", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toMutableList", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toMutableSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSortedSet", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "toSortedSet", "(Sequence,Comparator)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "unzip", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "windowed", "(Sequence,int,int,boolean,Function1)", "", "Argument[4]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "withIndex", "(Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.sequences", "SequencesKt", false, "zip", "(Sequence,Sequence,Function2)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "CharsKt", false, "plus", "(char,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "MatchGroup", "(String,IntRange)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "MatchGroup", "(String,IntRange)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "copy", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "copy", "(String,IntRange)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "getRange", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchGroup", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getDestructured", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getGroupValues", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "getGroups", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult", true, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component10", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component3", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component4", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component5", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component6", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component7", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component8", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "component9", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "getMatch", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "MatchResult$Destructured", false, "toList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "find", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "getOptions", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "matchEntire", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replace", "(CharSequence,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replaceFirst", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "replaceFirst", "(CharSequence,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex", false, "toPattern", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "Regex$Companion", false, "escape", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(byte[],int,int,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "String", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(Appendable,CharSequence[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "append", "(StringBuilder,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(Appendable,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuffer)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,StringBuilder)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,double)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,float)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendLine", "(StringBuilder,short)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(Appendable,CharSequence,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,CharSequence,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendRange", "(StringBuilder,char[],int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(Appendable,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuffer)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,StringBuilder)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,byte)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,char[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,double)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,float)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "appendln", "(StringBuilder,short)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateByTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateByTo", "(CharSequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "associateWithTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "capitalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "capitalize", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "clear", "(StringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "concatToString", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "concatToString", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decapitalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decapitalize", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decodeToString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "decodeToString", "(byte[],int,int,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "drop", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "drop", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLast", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLast", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLastWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropLastWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "dropWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "encodeToByteArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "encodeToByteArray", "(String,int,int,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterIndexedTo", "(CharSequence,Appendable,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterNotTo", "(CharSequence,Appendable,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "filterTo", "(CharSequence,Appendable,Function1)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "findAnyOf", "(CharSequence,Collection,int,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "findLastAnyOf", "(CharSequence,Collection,int,boolean)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "flatMapIndexedIterableTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "flatMapTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "fold", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldRight", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "foldRightIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Locale,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Locale,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[3].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,String,Object[])", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "format", "(StringCompanionObject,String,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(String,Locale,Object[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(String,Locale,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "formatNullable", "(StringCompanionObject,Locale,String,Object[])", "", "Argument[3].ArrayElement", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "groupByTo", "(CharSequence,Map,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "groupByTo", "(CharSequence,Map,Function1,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "ifBlank", "(CharSequence,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "ifEmpty", "(CharSequence,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,CharSequence,int,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "insertRange", "(StringBuilder,int,char[],int,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "intern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lineSequence", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lines", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lowercase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "lowercase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapIndexedNotNullTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapIndexedTo", "(CharSequence,Collection,Function2)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapNotNullTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "mapTo", "(CharSequence,Collection,Function1)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "onEach", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "onEachIndexed", "(CharSequence,Function2)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "orEmpty", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "padEnd", "(CharSequence,int,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "padStart", "(CharSequence,int,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "prependIndent", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removePrefix", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removePrefix", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeRange", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeRange", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSuffix", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSuffix", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(CharSequence,CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(String,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "removeSurrounding", "(String,CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "repeat", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(CharSequence,Regex,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replace", "(String,char,char,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfter", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfter", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfterLast", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceAfterLast", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBefore", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBefore", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBeforeLast", "(String,String,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceBeforeLast", "(String,char,String,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(CharSequence,Regex,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(CharSequence,Regex,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(String,String,String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirst", "(String,char,char,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirstCharWithChar", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceFirstCharWithCharSequence", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,IntRange,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,IntRange,CharSequence)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,int,int,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "replaceRange", "(CharSequence,int,int,CharSequence)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "reversed", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "runningFold", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "runningFoldIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "scan", "(CharSequence,Object,Function2)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "scanIndexed", "(CharSequence,Object,Function3)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[3]", "Argument[0]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "setRange", "(StringBuilder,int,int,String)", "", "Argument[3]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "slice", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "slice", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "split", "(CharSequence,Pattern,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "splitToSequence", "(CharSequence,String[],boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "splitToSequence", "(CharSequence,char[],boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "subSequence", "(CharSequence,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "subSequence", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,IntRange)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substring", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfter", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringAfterLast", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBefore", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,char,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "substringBeforeLast", "(String,char,String)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "take", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "take", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLast", "(CharSequence,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLast", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLastWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeLastWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeWhile", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "takeWhile", "(String,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toByteArray", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,char[],int,int,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCharArray", "(StringBuilder,char[],int,int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toCollection", "(CharSequence,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toLowerCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toLowerCase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toRegex", "(Pattern)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toUpperCase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "toUpperCase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trim", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimEnd", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "trimStart", "(CharSequence,char[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "uppercase", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.text", "StringsKt", false, "uppercase", "(String,Locale)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "div", "(double)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "div", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "getAbsoluteValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "minus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "plus", "(Duration)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin.time", "Duration", false, "times", "(double)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration", false, "times", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration$Companion", false, "getINFINITE", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "Duration$Companion", false, "getZERO", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "DurationKt", false, "times", "(double,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "DurationKt", false, "times", "(int,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "minus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "plus", "(Duration)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeMark", true, "plus", "(Duration)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimeSource", true, "markNow", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "TimedValue", "(Object,Duration)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "TimedValue", "(Object,Duration)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "copy", "(Object,Duration)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "copy", "(Object,Duration)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "getDuration", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin.time", "TimedValue", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "DeepRecursiveFunction", false, "DeepRecursiveFunction", "(SuspendFunction2)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "KotlinVersion$Companion", false, "getCURRENT", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "getValue", "(Lazy,Object,KProperty)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(LazyThreadSafetyMode,Function0)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazy", "(Object,Function0)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "LazyKt", false, "lazyOf", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "Pair", "(Object,Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Pair", false, "Pair", "(Object,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Pair", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "copy", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "copy", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "getFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "getSecond", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Pair", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "checkNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "checkNotNull", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "requireNotNull", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "PreconditionsKt", false, "requireNotNull", "(Object,Function0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "exceptionOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "getOrNull", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result$Companion", false, "failure", "(Throwable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Result$Companion", false, "success", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "fold", "(Result,Function1,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrDefault", "(Result,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrDefault", "(Result,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrElse", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "getOrThrow", "(Result)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "map", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "mapCatching", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "onFailure", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "onSuccess", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "recover", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "ResultKt", false, "recoverCatching", "(Result,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "also", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "apply", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "let", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "run", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "takeIf", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "takeUnless", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "StandardKt", false, "with", "(Object,Function1)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "SuspendKt", false, "suspend", "(SuspendFunction0)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "Triple", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["kotlin", "Triple", false, "component1", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "component2", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "component3", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "copy", "(Object,Object,Object)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getFirst", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getSecond", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "getThird", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "Triple", false, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "to", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "to", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "toList", "(Pair)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "TuplesKt", false, "toList", "(Triple)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["kotlin", "UByte", false, "toUByte", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UByteArrayKt", false, "ubyteArrayOf", "(UByteArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "UInt", false, "toUInt", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UIntArrayKt", false, "uintArrayOf", "(UIntArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "ULong", false, "toULong", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "ULongArrayKt", false, "ulongArrayOf", "(ULongArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["kotlin", "UShort", false, "toUShort", "()", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["kotlin", "UShortArrayKt", false, "ushortArrayOf", "(UShortArray)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["kotlin.annotation", "AnnotationRetention", "valueOf", "(String)", "generated"] + - ["kotlin.annotation", "AnnotationRetention", "values", "()", "generated"] + - ["kotlin.annotation", "AnnotationTarget", "valueOf", "(String)", "generated"] + - ["kotlin.annotation", "AnnotationTarget", "values", "()", "generated"] + - ["kotlin.annotation", "MustBeDocumented", "MustBeDocumented", "()", "generated"] + - ["kotlin.annotation", "Repeatable", "Repeatable", "()", "generated"] + - ["kotlin.annotation", "Retention", "Retention", "(AnnotationRetention)", "generated"] + - ["kotlin.annotation", "Retention", "value", "()", "generated"] + - ["kotlin.annotation", "Target", "Target", "(AnnotationTarget[])", "generated"] + - ["kotlin.annotation", "Target", "allowedTargets", "()", "generated"] + - ["kotlin.collections", "AbstractIterator", "AbstractIterator", "()", "generated"] + - ["kotlin.collections", "AbstractList", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractList", "hashCode", "()", "generated"] + - ["kotlin.collections", "AbstractMap", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractMap", "hashCode", "()", "generated"] + - ["kotlin.collections", "AbstractMap", "toString", "()", "generated"] + - ["kotlin.collections", "AbstractSet", "equals", "(Object)", "generated"] + - ["kotlin.collections", "AbstractSet", "hashCode", "()", "generated"] + - ["kotlin.collections", "ArrayDeque", "ArrayDeque", "()", "generated"] + - ["kotlin.collections", "ArrayDeque", "ArrayDeque", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "()", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "(Collection)", "generated"] + - ["kotlin.collections", "ArrayList", "ArrayList", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "ensureCapacity", "(int)", "generated"] + - ["kotlin.collections", "ArrayList", "trimToSize", "()", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "all", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "any", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asIterable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "asSequence", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associate", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(Object[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(boolean[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(byte[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(char[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(double[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(float[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(int[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(long[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateBy", "(short[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "associateWith", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "average", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfByte", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfDouble", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfFloat", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfInt", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfLong", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "averageOfShort", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(Object[],Object,Comparator,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(Object[],Object,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(byte[],byte,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(char[],char,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(double[],double,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(float[],float,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(long[],long,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "binarySearch", "(short[],short,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component1", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component2", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component3", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component4", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "component5", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "contains", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepEqualsInline", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepEqualsNullable", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepHashCodeInline", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepHashCodeNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepToStringInline", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentDeepToStringNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEquals", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(Object[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentEqualsNullable", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCode", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentHashCodeNullable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToString", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "contentToStringNullable", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(boolean[],boolean[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(double[],double[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(float[],float[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(int[],int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(long[],long[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyInto", "(short[],short[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOf", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(boolean[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "copyOfRangeInline", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "count", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinct", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "distinctBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "drop", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLast", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropLastWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "dropWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAt", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(Object[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(boolean[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(byte[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(char[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(double[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(float[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(int[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(long[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrElse", "(short[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "elementAtOrNull", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(boolean[],boolean,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(byte[],byte,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(char[],char,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(double[],double,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(float[],float,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(int[],int,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(long[],long,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "fill", "(short[],short,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filter", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIsInstance", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "filterIsInstance", "(Object[],Class)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNot", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "filterNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "find", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "findLast", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "first", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstNotNullOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstNotNullOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "firstOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMap", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedIterable", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapIndexedSequence", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatMapSequence", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "flatten", "(Object[][])", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEach", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "forEachIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getIndices", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getLastIndex", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(Object[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(boolean[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(byte[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(char[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(double[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(float[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(int[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(long[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrElse", "(short[],int,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(Object[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "getOrNull", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(Object[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(boolean[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(byte[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(char[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(double[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(float[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(int[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(long[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupBy", "(short[],Function1,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "groupingBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOf", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfFirst", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "indexOfLast", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "intersect", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isEmpty", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNotEmpty", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "isNullOrEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "last", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(Object[],Object)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(byte[],byte)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(char[],char)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastIndexOf", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "lastOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "map", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapIndexedNotNull", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "mapNotNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "max", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxByOrThrow", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOf", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWith", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOfWithOrNull", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxOrThrow", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrNull", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "maxWithOrThrow", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "min", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minByOrThrow", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOf", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWith", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(boolean[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(byte[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(char[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(double[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(float[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(int[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(long[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOfWithOrNull", "(short[],Comparator,Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minOrThrow", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrNull", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "minWithOrThrow", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "none", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEach", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "onEachIndexed", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "partition", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],boolean)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],double)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],float)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],long)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],short)", "generated"] + - ["kotlin.collections", "ArraysKt", "plus", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "random", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "randomOrNull", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduce", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceIndexedOrNull", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceOrNull", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRight", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightIndexedOrNull", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reduceRightOrNull", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(Object[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(boolean[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reverse", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversed", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "reversedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduce", "(short[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(Object[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(boolean[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(byte[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(char[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(double[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(float[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(int[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(long[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "runningReduceIndexed", "(short[],Function3)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(Object[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(boolean[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(byte[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(char[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(double[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(float[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(int[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(long[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "shuffle", "(short[],Random)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "single", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "singleOrNull", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(boolean[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(byte[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(char[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(double[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(float[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(int[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(long[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(short[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "slice", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(boolean[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(boolean[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(byte[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(char[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(double[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(double[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(float[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(float[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(int[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(int[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(long[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(long[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(short[],Collection)", "generated"] + - ["kotlin.collections", "ArraysKt", "sliceArray", "(short[],IntRange)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Comparable[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(Object[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sort", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortByDescending", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(Comparable[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(byte[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(char[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(double[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(float[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(int[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(long[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortDescending", "(short[],int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortWith", "(Object[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortWith", "(Object[],Comparator,int,int)", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sorted", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedArrayDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedByDescending", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedDescending", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(boolean[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(byte[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(char[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(double[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(float[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(int[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(long[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "sortedWith", "(short[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(Object[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "subtract", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sum", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumBy", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumByDouble", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigDecimal", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfBigInteger", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfByte", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfDouble", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfFloat", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfInt", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfLong", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfShort", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfUInt", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "sumOfULong", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "take", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(boolean[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(byte[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(char[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(double[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(float[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(int[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(long[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLast", "(short[],int)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeLastWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(Object[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(boolean[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(byte[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(char[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(double[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(float[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(int[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(long[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "takeWhile", "(short[],Function1)", "generated"] + - ["kotlin.collections", "ArraysKt", "toBooleanArray", "(Boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toByteArray", "(Byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toCharArray", "(Character[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toDoubleArray", "(Double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toFloatArray", "(Float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toHashSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toIntArray", "(Integer[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toLongArray", "(Long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableList", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toMutableSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toShortArray", "(Short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(Comparable[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(Object[],Comparator)", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toSortedSet", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "toTypedArray", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "union", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "unzip", "(Pair[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "withIndex", "(short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],boolean[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(boolean[],boolean[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],byte[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(byte[],byte[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],char[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(char[],char[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],double[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(double[],double[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],float[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(float[],float[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],int[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(int[],int[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],long[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(long[],long[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Iterable)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Iterable,Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Object[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],Object[],Function2)", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],short[])", "generated"] + - ["kotlin.collections", "ArraysKt", "zip", "(short[],short[],Function2)", "generated"] + - ["kotlin.collections", "BooleanIterator", "BooleanIterator", "()", "generated"] + - ["kotlin.collections", "BooleanIterator", "nextBoolean", "()", "generated"] + - ["kotlin.collections", "ByteIterator", "ByteIterator", "()", "generated"] + - ["kotlin.collections", "ByteIterator", "nextByte", "()", "generated"] + - ["kotlin.collections", "CharIterator", "CharIterator", "()", "generated"] + - ["kotlin.collections", "CharIterator", "nextChar", "()", "generated"] + - ["kotlin.collections", "CollectionsHKt", "eachCount", "(Grouping)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "fill", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "orEmpty", "(Object[])", "generated"] + - ["kotlin.collections", "CollectionsHKt", "shuffle", "(List)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "shuffled", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "sort", "(List)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "sortWith", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsHKt", "toTypedArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "Iterable", "(Function0)", "generated"] + - ["kotlin.collections", "CollectionsKt", "List", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "MutableList", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "all", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "any", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "any", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "arrayListOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "asSequence", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfByte", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfDouble", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfFloat", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfInt", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfLong", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "averageOfShort", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,Comparable,int,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,Object,Comparator,int,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearch", "(List,int,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "binarySearchBy", "(List,Comparable,int,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "buildList", "(Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "buildList", "(int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "chunked", "(Iterable,int)", "generated"] + - ["kotlin.collections", "CollectionsKt", "chunked", "(Iterable,int,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "contains", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "containsAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "count", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "emptyList", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "filterIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMap", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapIndexedIterable", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapIndexedSequence", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "flatMapSequence", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEach", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEach", "(Iterator,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "forEachIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "getIndices", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "getLastIndex", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupBy", "(Iterable,Function1,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "groupingBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOf", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOf", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfFirst", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfFirst", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfLast", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "indexOfLast", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "isNotEmpty", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "isNullOrEmpty", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "iterator", "(Enumeration)", "generated"] + - ["kotlin.collections", "CollectionsKt", "lastIndexOf", "(Iterable,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "lastIndexOf", "(List,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "listOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "listOfNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapIndexed", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapIndexedNotNull", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mapNotNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "max", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOf", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOfOrNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOrNull", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "maxOrThrow", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "min", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOf", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOfOrNull", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOrNull", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minOrThrow", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "minusAssign", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "mutableListOf", "()", "generated"] + - ["kotlin.collections", "CollectionsKt", "none", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "none", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "remove", "(Collection,Object)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "removeAll", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Object[])", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Collection,Sequence)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "retainAll", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "reverse", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "runningReduce", "(Iterable,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "runningReduceIndexed", "(Iterable,Function3)", "generated"] + - ["kotlin.collections", "CollectionsKt", "shuffle", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "shuffle", "(List,Random)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sort", "(List,Function2)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortBy", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortByDescending", "(List,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortDescending", "(List)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sortWith", "(List,Comparator)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumBy", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumByDouble", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfBigDecimal", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfBigInteger", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfByte", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfDouble", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfDouble", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfFloat", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfInt", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfInt", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfLong", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfLong", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfShort", "(Iterable)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfUInt", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "sumOfULong", "(Iterable,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toBooleanArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toByteArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toCharArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toDoubleArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toFloatArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toIntArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toLongArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "toShortArray", "(Collection)", "generated"] + - ["kotlin.collections", "CollectionsKt", "windowed", "(Iterable,int,int,boolean)", "generated"] + - ["kotlin.collections", "CollectionsKt", "windowed", "(Iterable,int,int,boolean,Function1)", "generated"] + - ["kotlin.collections", "CollectionsKt", "withIndex", "(Iterable)", "generated"] + - ["kotlin.collections", "DoubleIterator", "DoubleIterator", "()", "generated"] + - ["kotlin.collections", "DoubleIterator", "nextDouble", "()", "generated"] + - ["kotlin.collections", "FloatIterator", "FloatIterator", "()", "generated"] + - ["kotlin.collections", "FloatIterator", "nextFloat", "()", "generated"] + - ["kotlin.collections", "Grouping", "keyOf", "(Object)", "generated"] + - ["kotlin.collections", "Grouping", "sourceIterator", "()", "generated"] + - ["kotlin.collections", "GroupingKt", "aggregate", "(Grouping,Function4)", "generated"] + - ["kotlin.collections", "GroupingKt", "eachCount", "(Grouping)", "generated"] + - ["kotlin.collections", "GroupingKt", "fold", "(Grouping,Function2,Function3)", "generated"] + - ["kotlin.collections", "GroupingKt", "fold", "(Grouping,Object,Function2)", "generated"] + - ["kotlin.collections", "GroupingKt", "reduce", "(Grouping,Function3)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "()", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(Map)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(int)", "generated"] + - ["kotlin.collections", "HashMap", "HashMap", "(int,float)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "()", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(Collection)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(int)", "generated"] + - ["kotlin.collections", "HashSet", "HashSet", "(int,float)", "generated"] + - ["kotlin.collections", "IndexedValue", "component1", "()", "generated"] + - ["kotlin.collections", "IndexedValue", "equals", "(Object)", "generated"] + - ["kotlin.collections", "IndexedValue", "getIndex", "()", "generated"] + - ["kotlin.collections", "IndexedValue", "hashCode", "()", "generated"] + - ["kotlin.collections", "IntIterator", "IntIterator", "()", "generated"] + - ["kotlin.collections", "IntIterator", "nextInt", "()", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "()", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(Map)", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(int)", "generated"] + - ["kotlin.collections", "LinkedHashMap", "LinkedHashMap", "(int,float)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "()", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(Collection)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(int)", "generated"] + - ["kotlin.collections", "LinkedHashSet", "LinkedHashSet", "(int,float)", "generated"] + - ["kotlin.collections", "LongIterator", "LongIterator", "()", "generated"] + - ["kotlin.collections", "LongIterator", "nextLong", "()", "generated"] + - ["kotlin.collections", "MapsKt", "all", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "any", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "any", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "asSequence", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "buildMap", "(Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "buildMap", "(int,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "contains", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "containsKey", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "containsValue", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "count", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "count", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "emptyMap", "()", "generated"] + - ["kotlin.collections", "MapsKt", "flatMap", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "flatMapSequence", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "forEach", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "hashMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "hashMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "isNotEmpty", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "isNullOrEmpty", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "linkedMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "linkedMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "mapNotNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "mapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "mapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "maxOf", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "maxOfOrNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minOf", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minOfOrNull", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Iterable)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Object)", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Object[])", "generated"] + - ["kotlin.collections", "MapsKt", "minusAssign", "(Map,Sequence)", "generated"] + - ["kotlin.collections", "MapsKt", "mutableMapOf", "()", "generated"] + - ["kotlin.collections", "MapsKt", "mutableMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "none", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "none", "(Map,Function1)", "generated"] + - ["kotlin.collections", "MapsKt", "plusAssign", "(Map,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "putAll", "(Map,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "sortedMapOf", "(Comparator,Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "sortedMapOf", "(Pair[])", "generated"] + - ["kotlin.collections", "MapsKt", "toMap", "(Sequence)", "generated"] + - ["kotlin.collections", "MapsKt", "toProperties", "(Map)", "generated"] + - ["kotlin.collections", "MapsKt", "toSortedMap", "(Map,Comparator)", "generated"] + - ["kotlin.collections", "SetsKt", "buildSet", "(Function1)", "generated"] + - ["kotlin.collections", "SetsKt", "buildSet", "(int,Function1)", "generated"] + - ["kotlin.collections", "SetsKt", "emptySet", "()", "generated"] + - ["kotlin.collections", "SetsKt", "hashSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "hashSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "linkedSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "linkedSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "mutableSetOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "mutableSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "setOf", "()", "generated"] + - ["kotlin.collections", "SetsKt", "setOfNotNull", "(Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "sortedSetOf", "(Comparator,Object[])", "generated"] + - ["kotlin.collections", "SetsKt", "sortedSetOf", "(Object[])", "generated"] + - ["kotlin.collections", "ShortIterator", "ShortIterator", "()", "generated"] + - ["kotlin.collections", "ShortIterator", "nextShort", "()", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "all", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "any", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "asIntArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asList", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asLongArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asShortArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "asUIntArray", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "asULongArray", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "asUShortArray", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "associateWith", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UByteArray,byte,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UIntArray,int,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(ULongArray,long,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "binarySearch", "(UShortArray,short,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component1", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component2", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component3", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component4", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "component5", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UByteArray,UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentEquals", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "contentHashCode", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOf", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "copyOfRange", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "count", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "dropWhile", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAt", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UByteArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UIntArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(ULongArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrElse", "(UShortArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "elementAtOrNull", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UByteArray,byte,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UIntArray,int,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(ULongArray,long,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "fill", "(UShortArray,short,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filter", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "filterNot", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "find", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "findLast", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "first", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "firstOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMap", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "flatMapIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEach", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "forEachIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getIndices", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getLastIndex", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UByteArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UIntArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(ULongArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrElse", "(UShortArray,int,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UByteArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(ULongArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "getOrNull", "(UShortArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UByteArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UIntArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(ULongArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "groupBy", "(UShortArray,Function1,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UByteArray,byte)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOf", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfFirst", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "indexOfLast", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "last", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UByteArray,byte)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastIndexOf", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "lastOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "map", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "mapIndexed", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "max", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxByOrThrow-U", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOf", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWith", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOfWithOrNull", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxOrThrow-U", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWith", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrNull", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "maxWithOrThrow-U", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "min", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minByOrThrow-U", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOf", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWith", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UByteArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UIntArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(ULongArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOfWithOrNull", "(UShortArray,Comparator,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minOrThrow-U", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWith", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrNull", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UByteArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UIntArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(ULongArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "minWithOrThrow-U", "(UShortArray,Comparator)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "none", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UIntArray,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(ULongArray,long)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "plus", "(UShortArray,short)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "random", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "randomOrNull", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduce", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceIndexedOrNull", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceOrNull", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRight", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightIndexedOrNull", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reduceRightOrNull", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reverse", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "reversedArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduce", "(UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UByteArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UIntArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(ULongArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "runningReduceIndexed", "(UShortArray,Function3)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UByteArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UIntArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(ULongArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "shuffle", "(UShortArray,Random)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "single", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "singleOrNull", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UByteArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UByteArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UIntArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UIntArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(ULongArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(ULongArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UShortArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "slice", "(UShortArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UByteArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UIntArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UIntArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(ULongArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(ULongArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UShortArray,Collection)", "generated"] + - ["kotlin.collections", "UArraysKt", "sliceArray", "(UShortArray,IntRange)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sort", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UByteArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UIntArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(ULongArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortDescending", "(UShortArray,int,int)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sorted", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sortedDescending", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sum", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumBy", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumByDouble", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigDecimal", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfBigInteger", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfDouble", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfInt", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfLong", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUByte", "(byte[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUInt", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfULong", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "sumOfUShort", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UByteArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UIntArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(ULongArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "takeWhile", "(UShortArray,Function1)", "generated"] + - ["kotlin.collections", "UArraysKt", "toIntArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toLongArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toShortArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toTypedArray", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "toUIntArray", "(int[])", "generated"] + - ["kotlin.collections", "UArraysKt", "toULongArray", "(long[])", "generated"] + - ["kotlin.collections", "UArraysKt", "toUShortArray", "(short[])", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "withIndex", "(UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,UByteArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UByteArray,UByteArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,UIntArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UIntArray,UIntArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,ULongArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(ULongArray,ULongArray,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Iterable)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Iterable,Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Object[])", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,Object[],Function2)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,UShortArray)", "generated"] + - ["kotlin.collections", "UArraysKt", "zip", "(UShortArray,UShortArray,Function2)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUByte", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUInt", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfULong", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "sumOfUShort", "(Iterable)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUByteArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUIntArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toULongArray", "(Collection)", "generated"] + - ["kotlin.collections", "UCollectionsKt", "toUShortArray", "(Collection)", "generated"] + - ["kotlin.collections.builders", "SerializedCollection$Companion", "getTagList", "()", "generated"] + - ["kotlin.collections.builders", "SerializedCollection$Companion", "getTagSet", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareBy", "(Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareByDescending", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareByDescending", "(Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValues", "(Comparable,Comparable)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "compareValuesBy", "(Object,Object,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(byte,byte[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(double,double[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(float,float[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(int,int[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(long,long[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "maxOf", "(short,short[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(byte,byte[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double,double)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(double,double[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float,float)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(float,float[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(int,int[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(long,long[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "minOf", "(short,short[])", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "naturalOrder", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsFirst", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsFirst", "(Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsLast", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "nullsLast", "(Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "reverseOrder", "()", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "then", "(Comparator,Comparator)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenBy", "(Comparator,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenBy", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenByDescending", "(Comparator,Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenByDescending", "(Comparator,Function1)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenComparator", "(Comparator,Function2)", "generated"] + - ["kotlin.comparisons", "ComparisonsKt", "thenDescending", "(Comparator,Comparator)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,UByteArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,UIntArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,ULongArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,UShortArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "maxOf", "(short,short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,UByteArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(byte,byte,byte)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,UIntArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(int,int,int)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,ULongArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(long,long,long)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,UShortArray)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,short)", "generated"] + - ["kotlin.comparisons", "UComparisonsKt", "minOf", "(short,short,short)", "generated"] + - ["kotlin.concurrent", "LocksKt", "read", "(ReentrantReadWriteLock,Function0)", "generated"] + - ["kotlin.concurrent", "LocksKt", "withLock", "(Lock,Function0)", "generated"] + - ["kotlin.concurrent", "LocksKt", "write", "(ReentrantReadWriteLock,Function0)", "generated"] + - ["kotlin.concurrent", "ThreadsKt", "getOrSet", "(ThreadLocal,Function0)", "generated"] + - ["kotlin.concurrent", "ThreadsKt", "thread", "(boolean,boolean,ClassLoader,String,int,Function0)", "generated"] + - ["kotlin.concurrent", "TimersKt", "fixedRateTimer", "(String,boolean,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "fixedRateTimer", "(String,boolean,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,Date,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "schedule", "(Timer,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "scheduleAtFixedRate", "(Timer,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "scheduleAtFixedRate", "(Timer,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timer", "(String,boolean,Date,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timer", "(String,boolean,long,long,Function1)", "generated"] + - ["kotlin.concurrent", "TimersKt", "timerTask", "(Function1)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "callsInPlace", "(Function,InvocationKind)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returns", "()", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returns", "(Object)", "generated"] + - ["kotlin.contracts", "ContractBuilder", "returnsNotNull", "()", "generated"] + - ["kotlin.contracts", "ContractBuilderKt", "contract", "(Function1)", "generated"] + - ["kotlin.contracts", "ExperimentalContracts", "ExperimentalContracts", "()", "generated"] + - ["kotlin.contracts", "InvocationKind", "valueOf", "(String)", "generated"] + - ["kotlin.contracts", "InvocationKind", "values", "()", "generated"] + - ["kotlin.contracts", "SimpleEffect", "implies", "(boolean)", "generated"] + - ["kotlin.coroutines", "Continuation", "getContext", "()", "generated"] + - ["kotlin.coroutines", "Continuation", "resumeWith", "(Result)", "generated"] + - ["kotlin.coroutines", "ContinuationInterceptor", "interceptContinuation", "(Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationInterceptor", "releaseInterceptedContinuation", "(Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "Continuation", "(CoroutineContext,Function1)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "createCoroutine", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "createCoroutine", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "getCoroutineContext", "()", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "resume", "(Continuation,Object)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "resumeWithException", "(Continuation,Throwable)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "startCoroutine", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "startCoroutine", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines", "ContinuationKt", "suspendCoroutine", "(Function1)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "fold", "(Object,Function2)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "get", "(Key)", "generated"] + - ["kotlin.coroutines", "CoroutineContext", "minusKey", "(Key)", "generated"] + - ["kotlin.coroutines", "CoroutineContext$Element", "getKey", "()", "generated"] + - ["kotlin.coroutines", "EmptyCoroutineContext", "hashCode", "()", "generated"] + - ["kotlin.coroutines", "EmptyCoroutineContext", "toString", "()", "generated"] + - ["kotlin.coroutines", "RestrictsSuspension", "RestrictsSuspension", "()", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationException", "CancellationException", "()", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationException", "CancellationException", "(String)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionHKt", "CancellationException", "(String,Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionHKt", "CancellationException", "(Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionKt", "CancellationException", "(String,Throwable)", "generated"] + - ["kotlin.coroutines.cancellation", "CancellationExceptionKt", "CancellationException", "(Throwable)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "createCoroutineUnintercepted", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "createCoroutineUnintercepted", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "intercepted", "(Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "CoroutinesIntrinsicsHKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "createCoroutineUnintercepted", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "createCoroutineUnintercepted", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "getCOROUTINE_SUSPENDED", "()", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction0,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "startCoroutineUninterceptedOrReturn", "(SuspendFunction1,Object,Continuation)", "generated"] + - ["kotlin.coroutines.intrinsics", "IntrinsicsKt", "suspendCoroutineUninterceptedOrReturn", "(Function1)", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", "getCallerFrame", "()", "generated"] + - ["kotlin.coroutines.jvm.internal", "CoroutineStackFrame", "getStackTraceElement", "()", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "and", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "and", "(short,short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "inv", "(byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "inv", "(short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "or", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "or", "(short,short)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "xor", "(byte,byte)", "generated"] + - ["kotlin.experimental", "BitwiseOperationsKt", "xor", "(short,short)", "generated"] + - ["kotlin.experimental", "ExperimentalTypeInference", "ExperimentalTypeInference", "()", "generated"] + - ["kotlin.io", "ByteStreamsKt", "bufferedWriter", "(OutputStream,Charset)", "generated"] + - ["kotlin.io", "ByteStreamsKt", "iterator", "(BufferedInputStream)", "generated"] + - ["kotlin.io", "ByteStreamsKt", "writer", "(OutputStream,Charset)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(Object)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(boolean)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(byte)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(char)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(char[])", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(double)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(float)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(int)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(long)", "generated"] + - ["kotlin.io", "ConsoleKt", "print", "(short)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(Object)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(boolean)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(byte)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(char)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(char[])", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(double)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(float)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(int)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(long)", "generated"] + - ["kotlin.io", "ConsoleKt", "println", "(short)", "generated"] + - ["kotlin.io", "ConsoleKt", "readLine", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "readln", "()", "generated"] + - ["kotlin.io", "ConsoleKt", "readlnOrNull", "()", "generated"] + - ["kotlin.io", "ConstantsKt", "getDEFAULT_BUFFER_SIZE", "()", "generated"] + - ["kotlin.io", "FileWalkDirection", "valueOf", "(String)", "generated"] + - ["kotlin.io", "FileWalkDirection", "values", "()", "generated"] + - ["kotlin.io", "FilesKt", "appendBytes", "(File,byte[])", "generated"] + - ["kotlin.io", "FilesKt", "appendText", "(File,String,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "bufferedReader", "(File,Charset,int)", "generated"] + - ["kotlin.io", "FilesKt", "bufferedWriter", "(File,Charset,int)", "generated"] + - ["kotlin.io", "FilesKt", "copyRecursively", "(File,File,boolean,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "createTempDir", "(String,String,File)", "generated"] + - ["kotlin.io", "FilesKt", "createTempFile", "(String,String,File)", "generated"] + - ["kotlin.io", "FilesKt", "deleteRecursively", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "endsWith", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "endsWith", "(File,String)", "generated"] + - ["kotlin.io", "FilesKt", "forEachBlock", "(File,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "forEachBlock", "(File,int,Function2)", "generated"] + - ["kotlin.io", "FilesKt", "forEachLine", "(File,Charset,Function1)", "generated"] + - ["kotlin.io", "FilesKt", "getExtension", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "getInvariantSeparatorsPath", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "getNameWithoutExtension", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "inputStream", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "isRooted", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "normalize", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "outputStream", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "printWriter", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "readBytes", "(File)", "generated"] + - ["kotlin.io", "FilesKt", "readLines", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "readText", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "reader", "(File,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "relativeTo", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "relativeToOrNull", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "startsWith", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "startsWith", "(File,String)", "generated"] + - ["kotlin.io", "FilesKt", "toRelativeString", "(File,File)", "generated"] + - ["kotlin.io", "FilesKt", "useLines", "(File,Charset,Function1)", "generated"] + - ["kotlin.io", "FilesKt", "writeBytes", "(File,byte[])", "generated"] + - ["kotlin.io", "FilesKt", "writeText", "(File,String,Charset)", "generated"] + - ["kotlin.io", "FilesKt", "writer", "(File,Charset)", "generated"] + - ["kotlin.io", "IoHKt", "print", "(Object)", "generated"] + - ["kotlin.io", "IoHKt", "println", "()", "generated"] + - ["kotlin.io", "IoHKt", "println", "(Object)", "generated"] + - ["kotlin.io", "IoHKt", "readln", "()", "generated"] + - ["kotlin.io", "IoHKt", "readlnOrNull", "()", "generated"] + - ["kotlin.io", "OnErrorAction", "valueOf", "(String)", "generated"] + - ["kotlin.io", "OnErrorAction", "values", "()", "generated"] + - ["kotlin.io", "TextStreamsKt", "readBytes", "(URL)", "generated"] + - ["kotlin.io", "TextStreamsKt", "readLines", "(Reader)", "generated"] + - ["kotlin.io", "TextStreamsKt", "readText", "(URL,Charset)", "generated"] + - ["kotlin.js", "ExperimentalJsExport", "ExperimentalJsExport", "()", "generated"] + - ["kotlin.js", "JsExport", "JsExport", "()", "generated"] + - ["kotlin.js", "JsName", "JsName", "(String)", "generated"] + - ["kotlin.js", "JsName", "name", "()", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getAnnotationClass", "(Annotation)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getDeclaringJavaClass", "(Enum)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaClass", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaClass", "(Object)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaObjectType", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getJavaPrimitiveType", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "getRuntimeClassOfKClassInstance", "(KClass)", "generated"] + - ["kotlin.jvm", "JvmClassMappingKt", "isArrayOf", "(Object[])", "generated"] + - ["kotlin.jvm", "JvmDefault", "JvmDefault", "()", "generated"] + - ["kotlin.jvm", "JvmDefaultWithCompatibility", "JvmDefaultWithCompatibility", "()", "generated"] + - ["kotlin.jvm", "JvmDefaultWithoutCompatibility", "JvmDefaultWithoutCompatibility", "()", "generated"] + - ["kotlin.jvm", "JvmField", "JvmField", "()", "generated"] + - ["kotlin.jvm", "JvmInline", "JvmInline", "()", "generated"] + - ["kotlin.jvm", "JvmMultifileClass", "JvmMultifileClass", "()", "generated"] + - ["kotlin.jvm", "JvmName", "JvmName", "(String)", "generated"] + - ["kotlin.jvm", "JvmName", "name", "()", "generated"] + - ["kotlin.jvm", "JvmOverloads", "JvmOverloads", "()", "generated"] + - ["kotlin.jvm", "JvmRecord", "JvmRecord", "()", "generated"] + - ["kotlin.jvm", "JvmStatic", "JvmStatic", "()", "generated"] + - ["kotlin.jvm", "JvmSuppressWildcards", "JvmSuppressWildcards", "(boolean)", "generated"] + - ["kotlin.jvm", "JvmSuppressWildcards", "suppress", "()", "generated"] + - ["kotlin.jvm", "JvmSynthetic", "JvmSynthetic", "()", "generated"] + - ["kotlin.jvm", "JvmWildcard", "JvmWildcard", "()", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "()", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(String)", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(String,Throwable)", "generated"] + - ["kotlin.jvm", "KotlinReflectionNotSupportedError", "KotlinReflectionNotSupportedError", "(Throwable)", "generated"] + - ["kotlin.jvm", "PurelyImplements", "PurelyImplements", "(String)", "generated"] + - ["kotlin.jvm", "PurelyImplements", "value", "()", "generated"] + - ["kotlin.jvm", "Strictfp", "Strictfp", "()", "generated"] + - ["kotlin.jvm", "Synchronized", "Synchronized", "()", "generated"] + - ["kotlin.jvm", "Throws", "Throws", "(KClass[])", "generated"] + - ["kotlin.jvm", "Throws", "exceptionClasses", "()", "generated"] + - ["kotlin.jvm", "Transient", "Transient", "()", "generated"] + - ["kotlin.jvm", "Volatile", "Volatile", "()", "generated"] + - ["kotlin.jvm.functions", "Function0", "invoke", "()", "generated"] + - ["kotlin.jvm.functions", "Function1", "invoke", "(Object)", "generated"] + - ["kotlin.jvm.functions", "Function10", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function11", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function12", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function13", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function14", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function15", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function16", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function17", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function18", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function19", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function2", "invoke", "(Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function20", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function21", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function22", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function3", "invoke", "(Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function4", "invoke", "(Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function5", "invoke", "(Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function6", "invoke", "(Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function7", "invoke", "(Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function8", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "Function9", "invoke", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.functions", "FunctionN", "invoke", "(Object[])", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "getOwner", "()", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "AdaptedFunctionReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(boolean[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(double[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(float[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(int[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(long[])", "generated"] + - ["kotlin.jvm.internal", "ArrayIteratorsKt", "iterator", "(short[])", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "BooleanSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "add", "(boolean)", "generated"] + - ["kotlin.jvm.internal", "BooleanSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", "ByteSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "ByteSpreadBuilder", "add", "(byte)", "generated"] + - ["kotlin.jvm.internal", "CallableReference", "CallableReference", "()", "generated"] + - ["kotlin.jvm.internal", "CallableReference", "getOwner", "()", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", "CharSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "CharSpreadBuilder", "add", "(char)", "generated"] + - ["kotlin.jvm.internal", "ClassBasedDeclarationContainer", "getJClass", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "ClassReference", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "ClassReference$Companion", "isInstance", "(Object,Class)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "DoubleSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "add", "(double)", "generated"] + - ["kotlin.jvm.internal", "DoubleSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "FloatSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "add", "(float)", "generated"] + - ["kotlin.jvm.internal", "FloatSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "FunInterfaceConstructorReference", "(Class)", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "FunInterfaceConstructorReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionAdapter", "getFunctionDelegate", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionBase", "getArity", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "FunctionImpl", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "getArity", "()", "generated"] + - ["kotlin.jvm.internal", "FunctionImpl", "invokeVararg", "(Object[])", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "FunctionReference", "(int)", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "FunctionReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "InlineMarker", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "afterInlineCall", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "beforeInlineCall", "()", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "finallyEnd", "(int)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "finallyStart", "(int)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "mark", "(String)", "generated"] + - ["kotlin.jvm.internal", "InlineMarker", "mark", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "IntSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "add", "(int)", "generated"] + - ["kotlin.jvm.internal", "IntSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Double,Double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Double,double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Float,Float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Float,float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(Object,Object)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(double,Double)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "areEqual", "(float,Float)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkExpressionValueIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkFieldIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkFieldIsNotNull", "(Object,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkHasClass", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkHasClass", "(String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNull", "(Object)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNullExpressionValue", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkNotNullParameter", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkParameterIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkReturnedValueIsNotNull", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "checkReturnedValueIsNotNull", "(Object,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "compare", "(int,int)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "compare", "(long,long)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "needClassReification", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "needClassReification", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "reifiedOperationMarker", "(int,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "reifiedOperationMarker", "(int,String,String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwAssert", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwAssert", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalArgument", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalArgument", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalState", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwIllegalState", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwJavaNpe", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwJavaNpe", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwNpe", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwNpe", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUndefinedForReified", "()", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUndefinedForReified", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUninitializedProperty", "(String)", "generated"] + - ["kotlin.jvm.internal", "Intrinsics", "throwUninitializedPropertyAccessException", "(String)", "generated"] + - ["kotlin.jvm.internal", "KTypeBase", "getJavaType", "()", "generated"] + - ["kotlin.jvm.internal", "Lambda", "Lambda", "(int)", "generated"] + - ["kotlin.jvm.internal", "Lambda", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "LocalVariableReference", "LocalVariableReference", "()", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "LongSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "add", "(long)", "generated"] + - ["kotlin.jvm.internal", "LongSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "MagicApiIntrinsics", "()", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "anyMagicApiCall", "(int,long,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,Object,Object,Object,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "intMagicApiCall", "(int,long,long,Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "voidMagicApiCall", "(Object)", "generated"] + - ["kotlin.jvm.internal", "MagicApiIntrinsics", "voidMagicApiCall", "(int)", "generated"] + - ["kotlin.jvm.internal", "MutableLocalVariableReference", "MutableLocalVariableReference", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference", "MutablePropertyReference", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference0", "MutablePropertyReference0", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference1", "MutablePropertyReference1", "()", "generated"] + - ["kotlin.jvm.internal", "MutablePropertyReference2", "MutablePropertyReference2", "()", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "PackageReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "PrimitiveSpreadBuilder", "PrimitiveSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "PropertyReference", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "PropertyReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference0", "PropertyReference0", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference1", "PropertyReference1", "()", "generated"] + - ["kotlin.jvm.internal", "PropertyReference2", "PropertyReference2", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$BooleanRef", "BooleanRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$BooleanRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ByteRef", "ByteRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ByteRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$CharRef", "CharRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$CharRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$DoubleRef", "DoubleRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$DoubleRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$FloatRef", "FloatRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$FloatRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$IntRef", "IntRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$IntRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$LongRef", "LongRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$LongRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ObjectRef", "ObjectRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ObjectRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ShortRef", "ShortRef", "()", "generated"] + - ["kotlin.jvm.internal", "Ref$ShortRef", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "Reflection", "Reflection", "()", "generated"] + - ["kotlin.jvm.internal", "Reflection", "createKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "createKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinClasses", "(Class[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "getOrCreateKotlinPackage", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "nullableTypeOf", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "nullableTypeOf", "(Class,KTypeProjection[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "renderLambdaToString", "(FunctionBase)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "renderLambdaToString", "(Lambda)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "setUpperBounds", "(KTypeParameter,KType[])", "generated"] + - ["kotlin.jvm.internal", "Reflection", "typeOf", "(Class)", "generated"] + - ["kotlin.jvm.internal", "Reflection", "typeOf", "(Class,KTypeProjection[])", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "ReflectionFactory", "()", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "createKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "createKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "getOrCreateKotlinClass", "(Class)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "getOrCreateKotlinClass", "(Class,String)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "renderLambdaToString", "(FunctionBase)", "generated"] + - ["kotlin.jvm.internal", "ReflectionFactory", "renderLambdaToString", "(Lambda)", "generated"] + - ["kotlin.jvm.internal", "SerializedIr", "SerializedIr", "(String[])", "generated"] + - ["kotlin.jvm.internal", "SerializedIr", "b", "()", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "ShortSpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "add", "(short)", "generated"] + - ["kotlin.jvm.internal", "ShortSpreadBuilder", "toArray", "()", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", "SpreadBuilder", "(int)", "generated"] + - ["kotlin.jvm.internal", "SpreadBuilder", "size", "()", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "TypeIntrinsics", "()", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "getFunctionArity", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isFunctionOfArity", "(Object,int)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableCollection", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableIterable", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableIterator", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableList", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableListIterator", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableMap", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableMapEntry", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "isMutableSet", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(ClassCastException)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(Object,String)", "generated"] + - ["kotlin.jvm.internal", "TypeIntrinsics", "throwCce", "(String)", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "hashCode", "()", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference", "toString", "()", "generated"] + - ["kotlin.jvm.internal", "TypeParameterReference$Companion", "toString", "(KTypeParameter)", "generated"] + - ["kotlin.jvm.internal", "TypeReference", "equals", "(Object)", "generated"] + - ["kotlin.jvm.internal", "TypeReference", "hashCode", "()", "generated"] + - ["kotlin.math", "MathKt", "IEEErem", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "IEEErem", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(double)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(float)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(int)", "generated"] + - ["kotlin.math", "MathKt", "abs", "(long)", "generated"] + - ["kotlin.math", "MathKt", "acos", "(double)", "generated"] + - ["kotlin.math", "MathKt", "acos", "(float)", "generated"] + - ["kotlin.math", "MathKt", "acosh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "acosh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "asin", "(double)", "generated"] + - ["kotlin.math", "MathKt", "asin", "(float)", "generated"] + - ["kotlin.math", "MathKt", "asinh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "asinh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "atan", "(double)", "generated"] + - ["kotlin.math", "MathKt", "atan", "(float)", "generated"] + - ["kotlin.math", "MathKt", "atan2", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "atan2", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "atanh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "atanh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cbrt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cbrt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "ceil", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ceil", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cos", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cos", "(float)", "generated"] + - ["kotlin.math", "MathKt", "cosh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "cosh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "exp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "exp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "expm1", "(double)", "generated"] + - ["kotlin.math", "MathKt", "expm1", "(float)", "generated"] + - ["kotlin.math", "MathKt", "floor", "(double)", "generated"] + - ["kotlin.math", "MathKt", "floor", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(int)", "generated"] + - ["kotlin.math", "MathKt", "getAbsoluteValue", "(long)", "generated"] + - ["kotlin.math", "MathKt", "getE", "()", "generated"] + - ["kotlin.math", "MathKt", "getPI", "()", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(float)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(int)", "generated"] + - ["kotlin.math", "MathKt", "getSign", "(long)", "generated"] + - ["kotlin.math", "MathKt", "getUlp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "getUlp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "hypot", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "hypot", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "ln", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ln", "(float)", "generated"] + - ["kotlin.math", "MathKt", "ln1p", "(double)", "generated"] + - ["kotlin.math", "MathKt", "ln1p", "(float)", "generated"] + - ["kotlin.math", "MathKt", "log", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "log", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "log10", "(double)", "generated"] + - ["kotlin.math", "MathKt", "log10", "(float)", "generated"] + - ["kotlin.math", "MathKt", "log2", "(double)", "generated"] + - ["kotlin.math", "MathKt", "log2", "(float)", "generated"] + - ["kotlin.math", "MathKt", "max", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "max", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "max", "(int,int)", "generated"] + - ["kotlin.math", "MathKt", "max", "(long,long)", "generated"] + - ["kotlin.math", "MathKt", "min", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "min", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "min", "(int,int)", "generated"] + - ["kotlin.math", "MathKt", "min", "(long,long)", "generated"] + - ["kotlin.math", "MathKt", "nextDown", "(double)", "generated"] + - ["kotlin.math", "MathKt", "nextDown", "(float)", "generated"] + - ["kotlin.math", "MathKt", "nextTowards", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "nextTowards", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "nextUp", "(double)", "generated"] + - ["kotlin.math", "MathKt", "nextUp", "(float)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(double,int)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "pow", "(float,int)", "generated"] + - ["kotlin.math", "MathKt", "round", "(double)", "generated"] + - ["kotlin.math", "MathKt", "round", "(float)", "generated"] + - ["kotlin.math", "MathKt", "roundToInt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "roundToInt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "roundToLong", "(double)", "generated"] + - ["kotlin.math", "MathKt", "roundToLong", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sign", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sign", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sin", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sin", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sinh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sinh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "sqrt", "(double)", "generated"] + - ["kotlin.math", "MathKt", "sqrt", "(float)", "generated"] + - ["kotlin.math", "MathKt", "tan", "(double)", "generated"] + - ["kotlin.math", "MathKt", "tan", "(float)", "generated"] + - ["kotlin.math", "MathKt", "tanh", "(double)", "generated"] + - ["kotlin.math", "MathKt", "tanh", "(float)", "generated"] + - ["kotlin.math", "MathKt", "truncate", "(double)", "generated"] + - ["kotlin.math", "MathKt", "truncate", "(float)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(double,double)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(double,int)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(float,float)", "generated"] + - ["kotlin.math", "MathKt", "withSign", "(float,int)", "generated"] + - ["kotlin.math", "UMathKt", "max", "(int,int)", "generated"] + - ["kotlin.math", "UMathKt", "max", "(long,long)", "generated"] + - ["kotlin.math", "UMathKt", "min", "(int,int)", "generated"] + - ["kotlin.math", "UMathKt", "min", "(long,long)", "generated"] + - ["kotlin.native", "CName", "CName", "(String,String)", "generated"] + - ["kotlin.native", "CName", "externName", "()", "generated"] + - ["kotlin.native", "CName", "shortName", "()", "generated"] + - ["kotlin.native.concurrent", "SharedImmutable", "SharedImmutable", "()", "generated"] + - ["kotlin.native.concurrent", "ThreadLocal", "ThreadLocal", "()", "generated"] + - ["kotlin.properties", "Delegates", "notNull", "()", "generated"] + - ["kotlin.properties", "Delegates", "observable", "(Object,Function3)", "generated"] + - ["kotlin.properties", "Delegates", "vetoable", "(Object,Function3)", "generated"] + - ["kotlin.properties", "PropertyDelegateProvider", "provideDelegate", "(Object,KProperty)", "generated"] + - ["kotlin.properties", "ReadOnlyProperty", "getValue", "(Object,KProperty)", "generated"] + - ["kotlin.properties", "ReadWriteProperty", "setValue", "(Object,KProperty,Object)", "generated"] + - ["kotlin.random", "Random", "Random", "()", "generated"] + - ["kotlin.random", "Random", "nextBits", "(int)", "generated"] + - ["kotlin.random", "Random", "nextBoolean", "()", "generated"] + - ["kotlin.random", "Random", "nextBytes", "(int)", "generated"] + - ["kotlin.random", "Random", "nextDouble", "()", "generated"] + - ["kotlin.random", "Random", "nextDouble", "(double)", "generated"] + - ["kotlin.random", "Random", "nextDouble", "(double,double)", "generated"] + - ["kotlin.random", "Random", "nextFloat", "()", "generated"] + - ["kotlin.random", "Random", "nextInt", "()", "generated"] + - ["kotlin.random", "Random", "nextInt", "(int)", "generated"] + - ["kotlin.random", "Random", "nextInt", "(int,int)", "generated"] + - ["kotlin.random", "Random", "nextLong", "()", "generated"] + - ["kotlin.random", "Random", "nextLong", "(long)", "generated"] + - ["kotlin.random", "Random", "nextLong", "(long,long)", "generated"] + - ["kotlin.random", "RandomKt", "Random", "(int)", "generated"] + - ["kotlin.random", "RandomKt", "Random", "(long)", "generated"] + - ["kotlin.random", "RandomKt", "nextInt", "(Random,IntRange)", "generated"] + - ["kotlin.random", "RandomKt", "nextLong", "(Random,LongRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextUBytes", "(Random,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,UIntRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextUInt", "(Random,int,int)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,ULongRange)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,long)", "generated"] + - ["kotlin.random", "URandomKt", "nextULong", "(Random,long,long)", "generated"] + - ["kotlin.ranges", "CharProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "CharProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "CharProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "CharProgression$Companion", "fromClosedRange", "(char,char,int)", "generated"] + - ["kotlin.ranges", "CharRange", "CharRange", "(char,char)", "generated"] + - ["kotlin.ranges", "CharRange", "contains", "(char)", "generated"] + - ["kotlin.ranges", "CharRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "CharRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "CharRange", "toString", "()", "generated"] + - ["kotlin.ranges", "ClosedFloatingPointRange", "lessThanOrEquals", "(Comparable,Comparable)", "generated"] + - ["kotlin.ranges", "ClosedRange", "contains", "(Comparable)", "generated"] + - ["kotlin.ranges", "ClosedRange", "getEndInclusive", "()", "generated"] + - ["kotlin.ranges", "ClosedRange", "getStart", "()", "generated"] + - ["kotlin.ranges", "ClosedRange", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "IntProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "IntProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "IntProgression$Companion", "fromClosedRange", "(int,int,int)", "generated"] + - ["kotlin.ranges", "IntRange", "IntRange", "(int,int)", "generated"] + - ["kotlin.ranges", "IntRange", "contains", "(int)", "generated"] + - ["kotlin.ranges", "IntRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "IntRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "IntRange", "toString", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "LongProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "LongProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "LongProgression$Companion", "fromClosedRange", "(long,long,long)", "generated"] + - ["kotlin.ranges", "LongRange", "LongRange", "(long,long)", "generated"] + - ["kotlin.ranges", "LongRange", "contains", "(long)", "generated"] + - ["kotlin.ranges", "LongRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "LongRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "LongRange", "toString", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "contains", "(Comparable)", "generated"] + - ["kotlin.ranges", "OpenEndRange", "getEndExclusive", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "getStart", "()", "generated"] + - ["kotlin.ranges", "OpenEndRange", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "byteRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtLeast", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceAtMost", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(byte,byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(double,double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(float,float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(int,ClosedRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(int,int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(long,ClosedRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(long,long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "coerceIn", "(short,short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(CharRange,Character)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(ClosedRange,Object)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,Integer)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(IntRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,Long)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(LongRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "contains", "(OpenEndRange,Object)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "doubleRangeContains", "(OpenEndRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "downTo", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "first", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "firstOrNull", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "floatRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "intRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "last", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "lastOrNull", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(ClosedRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "longRangeContains", "(OpenEndRange,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(CharRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(CharRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(IntRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(IntRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(LongRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "random", "(LongRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(CharRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(CharRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(IntRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(IntRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(LongRange)", "generated"] + - ["kotlin.ranges", "RangesKt", "randomOrNull", "(LongRange,Random)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeTo", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeTo", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(double,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(float,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "rangeUntil", "(short,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(CharProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(IntProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "reversed", "(LongProgression)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,double)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,float)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(ClosedRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "shortRangeContains", "(OpenEndRange,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(CharProgression,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(IntProgression,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "step", "(LongProgression,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(byte,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(char,char)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(int,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(long,short)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,byte)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,int)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,long)", "generated"] + - ["kotlin.ranges", "RangesKt", "until", "(short,short)", "generated"] + - ["kotlin.ranges", "UIntProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "UIntProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "UIntProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "UIntProgression$Companion", "fromClosedRange", "(int,int,int)", "generated"] + - ["kotlin.ranges", "UIntRange", "UIntRange", "(int,int)", "generated"] + - ["kotlin.ranges", "UIntRange", "contains", "(int)", "generated"] + - ["kotlin.ranges", "UIntRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "UIntRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "UIntRange", "toString", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "ULongProgression", "getFirst", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "getLast", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "getStep", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "hashCode", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "isEmpty", "()", "generated"] + - ["kotlin.ranges", "ULongProgression", "toString", "()", "generated"] + - ["kotlin.ranges", "ULongProgression$Companion", "fromClosedRange", "(long,long,long)", "generated"] + - ["kotlin.ranges", "ULongRange", "ULongRange", "(long,long)", "generated"] + - ["kotlin.ranges", "ULongRange", "contains", "(long)", "generated"] + - ["kotlin.ranges", "ULongRange", "equals", "(Object)", "generated"] + - ["kotlin.ranges", "ULongRange", "hashCode", "()", "generated"] + - ["kotlin.ranges", "ULongRange", "toString", "()", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtLeast", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceAtMost", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(byte,byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(int,ClosedRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(int,int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(long,ClosedRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(long,long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "coerceIn", "(short,short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,UInt)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(UIntRange,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,ULong)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "contains", "(ULongRange,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "downTo", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "first", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "first", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "firstOrNull", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "firstOrNull", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "last", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "last", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "lastOrNull", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "lastOrNull", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(UIntRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(UIntRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(ULongRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "random", "(ULongRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(UIntRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(UIntRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(ULongRange)", "generated"] + - ["kotlin.ranges", "URangesKt", "randomOrNull", "(ULongRange,Random)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "rangeUntil", "(short,short)", "generated"] + - ["kotlin.ranges", "URangesKt", "reversed", "(UIntProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "reversed", "(ULongProgression)", "generated"] + - ["kotlin.ranges", "URangesKt", "step", "(UIntProgression,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "step", "(ULongProgression,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(byte,byte)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(int,int)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(long,long)", "generated"] + - ["kotlin.ranges", "URangesKt", "until", "(short,short)", "generated"] + - ["kotlin.reflect", "KAnnotatedElement", "getAnnotations", "()", "generated"] + - ["kotlin.reflect", "KCallable", "call", "(Object[])", "generated"] + - ["kotlin.reflect", "KCallable", "callBy", "(Map)", "generated"] + - ["kotlin.reflect", "KCallable", "getName", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getParameters", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getReturnType", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getTypeParameters", "()", "generated"] + - ["kotlin.reflect", "KCallable", "getVisibility", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isAbstract", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isFinal", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isOpen", "()", "generated"] + - ["kotlin.reflect", "KCallable", "isSuspend", "()", "generated"] + - ["kotlin.reflect", "KClass", "equals", "(Object)", "generated"] + - ["kotlin.reflect", "KClass", "getConstructors", "()", "generated"] + - ["kotlin.reflect", "KClass", "getNestedClasses", "()", "generated"] + - ["kotlin.reflect", "KClass", "getObjectInstance", "()", "generated"] + - ["kotlin.reflect", "KClass", "getQualifiedName", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSealedSubclasses", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSimpleName", "()", "generated"] + - ["kotlin.reflect", "KClass", "getSupertypes", "()", "generated"] + - ["kotlin.reflect", "KClass", "getTypeParameters", "()", "generated"] + - ["kotlin.reflect", "KClass", "getVisibility", "()", "generated"] + - ["kotlin.reflect", "KClass", "hashCode", "()", "generated"] + - ["kotlin.reflect", "KClass", "isAbstract", "()", "generated"] + - ["kotlin.reflect", "KClass", "isCompanion", "()", "generated"] + - ["kotlin.reflect", "KClass", "isData", "()", "generated"] + - ["kotlin.reflect", "KClass", "isFinal", "()", "generated"] + - ["kotlin.reflect", "KClass", "isFun", "()", "generated"] + - ["kotlin.reflect", "KClass", "isInner", "()", "generated"] + - ["kotlin.reflect", "KClass", "isInstance", "(Object)", "generated"] + - ["kotlin.reflect", "KClass", "isOpen", "()", "generated"] + - ["kotlin.reflect", "KClass", "isSealed", "()", "generated"] + - ["kotlin.reflect", "KClass", "isValue", "()", "generated"] + - ["kotlin.reflect", "KDeclarationContainer", "getMembers", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isExternal", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isInfix", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isInline", "()", "generated"] + - ["kotlin.reflect", "KFunction", "isOperator", "()", "generated"] + - ["kotlin.reflect", "KMutableProperty", "getSetter", "()", "generated"] + - ["kotlin.reflect", "KMutableProperty0", "set", "(Object)", "generated"] + - ["kotlin.reflect", "KMutableProperty1", "set", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KMutableProperty2", "set", "(Object,Object,Object)", "generated"] + - ["kotlin.reflect", "KParameter", "getIndex", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getKind", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getName", "()", "generated"] + - ["kotlin.reflect", "KParameter", "getType", "()", "generated"] + - ["kotlin.reflect", "KParameter", "isOptional", "()", "generated"] + - ["kotlin.reflect", "KParameter", "isVararg", "()", "generated"] + - ["kotlin.reflect", "KParameter$Kind", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KParameter$Kind", "values", "()", "generated"] + - ["kotlin.reflect", "KProperty", "getGetter", "()", "generated"] + - ["kotlin.reflect", "KProperty", "isConst", "()", "generated"] + - ["kotlin.reflect", "KProperty", "isLateinit", "()", "generated"] + - ["kotlin.reflect", "KProperty$Accessor", "getProperty", "()", "generated"] + - ["kotlin.reflect", "KProperty0", "get", "()", "generated"] + - ["kotlin.reflect", "KProperty0", "getDelegate", "()", "generated"] + - ["kotlin.reflect", "KProperty1", "get", "(Object)", "generated"] + - ["kotlin.reflect", "KProperty1", "getDelegate", "(Object)", "generated"] + - ["kotlin.reflect", "KProperty2", "get", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KProperty2", "getDelegate", "(Object,Object)", "generated"] + - ["kotlin.reflect", "KType", "getArguments", "()", "generated"] + - ["kotlin.reflect", "KType", "getClassifier", "()", "generated"] + - ["kotlin.reflect", "KType", "isMarkedNullable", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getName", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getUpperBounds", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "getVariance", "()", "generated"] + - ["kotlin.reflect", "KTypeParameter", "isReified", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "component1", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "equals", "(Object)", "generated"] + - ["kotlin.reflect", "KTypeProjection", "getVariance", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection", "hashCode", "()", "generated"] + - ["kotlin.reflect", "KTypeProjection$Companion", "getSTAR", "()", "generated"] + - ["kotlin.reflect", "KVariance", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KVariance", "values", "()", "generated"] + - ["kotlin.reflect", "KVisibility", "valueOf", "(String)", "generated"] + - ["kotlin.reflect", "KVisibility", "values", "()", "generated"] + - ["kotlin.reflect", "TypeOfKt", "typeOf", "()", "generated"] + - ["kotlin.sequences", "Sequence", "iterator", "()", "generated"] + - ["kotlin.sequences", "SequenceScope", "yield", "(Object)", "generated"] + - ["kotlin.sequences", "SequenceScope", "yieldAll", "(Iterable)", "generated"] + - ["kotlin.sequences", "SequenceScope", "yieldAll", "(Iterator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "Sequence", "(Function0)", "generated"] + - ["kotlin.sequences", "SequencesKt", "all", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "any", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "any", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asIterable", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asSequence", "(Enumeration)", "generated"] + - ["kotlin.sequences", "SequencesKt", "asSequence", "(Iterator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "associate", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "associateBy", "(Sequence,Function1,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfDouble", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfFloat", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfLong", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "averageOfShort", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "chunked", "(Sequence,int)", "generated"] + - ["kotlin.sequences", "SequencesKt", "contains", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "count", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "count", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "emptySequence", "()", "generated"] + - ["kotlin.sequences", "SequencesKt", "filterIndexed", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "flatMapIndexedIterable", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "flatMapIndexedSequence", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "forEach", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "forEachIndexed", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupBy", "(Sequence,Function1,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "groupingBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "ifEmpty", "(Sequence,Function0)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOf", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOfFirst", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "indexOfLast", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "iterator", "(SuspendFunction1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "lastIndexOf", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "max", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOf", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOfOrNull", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOrNull", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "maxOrThrow", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "min", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOf", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOfOrNull", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOrNull", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minOrThrow", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Iterable)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minus", "(Sequence,Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "minusElement", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "none", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "none", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Iterable)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Object[])", "generated"] + - ["kotlin.sequences", "SequencesKt", "plus", "(Sequence,Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "plusElement", "(Sequence,Object)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningFold", "(Sequence,Object,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningFoldIndexed", "(Sequence,Object,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningReduce", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "runningReduceIndexed", "(Sequence,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "scan", "(Sequence,Object,Function2)", "generated"] + - ["kotlin.sequences", "SequencesKt", "scanIndexed", "(Sequence,Object,Function3)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sequence", "(SuspendFunction1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sequenceOf", "(Object[])", "generated"] + - ["kotlin.sequences", "SequencesKt", "shuffled", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "shuffled", "(Sequence,Random)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sorted", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedByDescending", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedDescending", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sortedWith", "(Sequence,Comparator)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumBy", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumByDouble", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfBigDecimal", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfBigInteger", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfDouble", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfDouble", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfFloat", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfInt", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfLong", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfLong", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfShort", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfUInt", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "sumOfULong", "(Sequence,Function1)", "generated"] + - ["kotlin.sequences", "SequencesKt", "windowed", "(Sequence,int,int,boolean)", "generated"] + - ["kotlin.sequences", "SequencesKt", "zipWithNext", "(Sequence)", "generated"] + - ["kotlin.sequences", "SequencesKt", "zipWithNext", "(Sequence,Function2)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUByte", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUInt", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfULong", "(Sequence)", "generated"] + - ["kotlin.sequences", "USequencesKt", "sumOfUShort", "(Sequence)", "generated"] + - ["kotlin.system", "ProcessKt", "exitProcess", "(int)", "generated"] + - ["kotlin.system", "TimingKt", "measureNanoTime", "(Function0)", "generated"] + - ["kotlin.system", "TimingKt", "measureTimeMillis", "(Function0)", "generated"] + - ["kotlin.text", "Appendable", "append", "(CharSequence)", "generated"] + - ["kotlin.text", "Appendable", "append", "(CharSequence,int,int)", "generated"] + - ["kotlin.text", "Appendable", "append", "(char)", "generated"] + - ["kotlin.text", "CharCategory", "contains", "(char)", "generated"] + - ["kotlin.text", "CharCategory", "getCode", "()", "generated"] + - ["kotlin.text", "CharCategory", "getValue", "()", "generated"] + - ["kotlin.text", "CharCategory", "valueOf", "(String)", "generated"] + - ["kotlin.text", "CharCategory", "values", "()", "generated"] + - ["kotlin.text", "CharCategory$Companion", "valueOf", "(int)", "generated"] + - ["kotlin.text", "CharDirectionality", "getValue", "()", "generated"] + - ["kotlin.text", "CharDirectionality", "valueOf", "(String)", "generated"] + - ["kotlin.text", "CharDirectionality", "values", "()", "generated"] + - ["kotlin.text", "CharDirectionality$Companion", "valueOf", "(int)", "generated"] + - ["kotlin.text", "CharacterCodingException", "CharacterCodingException", "()", "generated"] + - ["kotlin.text", "CharsKt", "digitToChar", "(int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToChar", "(int,int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToInt", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "digitToInt", "(char,int)", "generated"] + - ["kotlin.text", "CharsKt", "digitToIntOrNull", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "digitToIntOrNull", "(char,int)", "generated"] + - ["kotlin.text", "CharsKt", "equals", "(char,char,boolean)", "generated"] + - ["kotlin.text", "CharsKt", "getCategory", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "getDirectionality", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isDefined", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isDigit", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isHighSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isISOControl", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isIdentifierIgnorable", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isJavaIdentifierPart", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isJavaIdentifierStart", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLetter", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLetterOrDigit", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLowSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isLowerCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isSurrogate", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isTitleCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isUpperCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "isWhitespace", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "lowercase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "lowercase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "lowercaseChar", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "titlecase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "titlecase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "titlecaseChar", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toLowerCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toTitleCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "toUpperCase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "uppercase", "(char)", "generated"] + - ["kotlin.text", "CharsKt", "uppercase", "(char,Locale)", "generated"] + - ["kotlin.text", "CharsKt", "uppercaseChar", "(char)", "generated"] + - ["kotlin.text", "Charsets", "UTF32", "()", "generated"] + - ["kotlin.text", "Charsets", "UTF32_BE", "()", "generated"] + - ["kotlin.text", "Charsets", "UTF32_LE", "()", "generated"] + - ["kotlin.text", "Charsets", "getISO_8859_1", "()", "generated"] + - ["kotlin.text", "Charsets", "getUS_ASCII", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16BE", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_16LE", "()", "generated"] + - ["kotlin.text", "Charsets", "getUTF_8", "()", "generated"] + - ["kotlin.text", "CharsetsKt", "charset", "(String)", "generated"] + - ["kotlin.text", "FlagEnum", "getMask", "()", "generated"] + - ["kotlin.text", "FlagEnum", "getValue", "()", "generated"] + - ["kotlin.text", "MatchGroup", "equals", "(Object)", "generated"] + - ["kotlin.text", "MatchGroup", "hashCode", "()", "generated"] + - ["kotlin.text", "MatchGroupCollection", "get", "(int)", "generated"] + - ["kotlin.text", "MatchNamedGroupCollection", "get", "(String)", "generated"] + - ["kotlin.text", "MatchResult", "getGroupValues", "()", "generated"] + - ["kotlin.text", "MatchResult", "getGroups", "()", "generated"] + - ["kotlin.text", "MatchResult", "getRange", "()", "generated"] + - ["kotlin.text", "MatchResult", "getValue", "()", "generated"] + - ["kotlin.text", "MatchResult", "next", "()", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String)", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String,RegexOption)", "generated"] + - ["kotlin.text", "Regex", "Regex", "(String,Set)", "generated"] + - ["kotlin.text", "Regex", "containsMatchIn", "(CharSequence)", "generated"] + - ["kotlin.text", "Regex", "findAll", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "getPattern", "()", "generated"] + - ["kotlin.text", "Regex", "matchAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "matches", "(CharSequence)", "generated"] + - ["kotlin.text", "Regex", "matchesAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "split", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "splitToSequence", "(CharSequence,int)", "generated"] + - ["kotlin.text", "Regex", "toString", "()", "generated"] + - ["kotlin.text", "Regex$Companion", "escapeReplacement", "(String)", "generated"] + - ["kotlin.text", "Regex$Companion", "fromLiteral", "(String)", "generated"] + - ["kotlin.text", "RegexOption", "valueOf", "(String)", "generated"] + - ["kotlin.text", "RegexOption", "values", "()", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "()", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(CharSequence)", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "StringBuilder", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(Object)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(boolean)", "generated"] + - ["kotlin.text", "StringBuilder", "append", "(char[])", "generated"] + - ["kotlin.text", "StringBuilder", "capacity", "()", "generated"] + - ["kotlin.text", "StringBuilder", "ensureCapacity", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "get", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "indexOf", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "indexOf", "(String,int)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,CharSequence)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,Object)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,String)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,boolean)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,char)", "generated"] + - ["kotlin.text", "StringBuilder", "insert", "(int,char[])", "generated"] + - ["kotlin.text", "StringBuilder", "lastIndexOf", "(String)", "generated"] + - ["kotlin.text", "StringBuilder", "lastIndexOf", "(String,int)", "generated"] + - ["kotlin.text", "StringBuilder", "reverse", "()", "generated"] + - ["kotlin.text", "StringBuilder", "setLength", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "substring", "(int)", "generated"] + - ["kotlin.text", "StringBuilder", "substring", "(int,int)", "generated"] + - ["kotlin.text", "StringBuilder", "trimToSize", "()", "generated"] + - ["kotlin.text", "StringsKt", "String", "(int[],int,int)", "generated"] + - ["kotlin.text", "StringsKt", "all", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "any", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "any", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "asIterable", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "asSequence", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "associate", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateBy", "(CharSequence,Function1,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "associateWith", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "buildString", "(Function1)", "generated"] + - ["kotlin.text", "StringsKt", "buildString", "(int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "chunked", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "chunked", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "chunkedSequence", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "chunkedSequence", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "codePointAt", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "codePointBefore", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "codePointCount", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "commonPrefixWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "commonSuffixWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "compareTo", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,Regex)", "generated"] + - ["kotlin.text", "StringsKt", "contains", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(CharSequence,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(String,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "contentEquals", "(String,StringBuffer)", "generated"] + - ["kotlin.text", "StringsKt", "count", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "count", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "deleteAt", "(StringBuilder,int)", "generated"] + - ["kotlin.text", "StringsKt", "deleteRange", "(StringBuilder,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "elementAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "elementAtOrElse", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "elementAtOrNull", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "endsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "equals", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "filter", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filter", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filterIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "filterIndexed", "(String,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "filterNot", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "filterNot", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "find", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "findLast", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "first", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "first", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstNotNullOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstNotNullOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "firstOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "firstOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "flatMap", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "flatMapIndexedIterable", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "forEach", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "forEachIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "getCASE_INSENSITIVE_ORDER", "(StringCompanionObject)", "generated"] + - ["kotlin.text", "StringsKt", "getIndices", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "getLastIndex", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "getOrElse", "(CharSequence,int,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "getOrNull", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "groupBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "groupBy", "(CharSequence,Function1,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "groupingBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "hasSurrogatePairAt", "(CharSequence,int)", "generated"] + - ["kotlin.text", "StringsKt", "indexOf", "(CharSequence,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOf", "(CharSequence,char,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfAny", "(CharSequence,Collection,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfAny", "(CharSequence,char[],int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfFirst", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "indexOfLast", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "isBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNotBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNotEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNullOrBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "isNullOrEmpty", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "iterator", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "last", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "last", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOf", "(CharSequence,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOf", "(CharSequence,char,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOfAny", "(CharSequence,Collection,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastIndexOfAny", "(CharSequence,char[],int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "lastOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "lastOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "map", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "mapIndexed", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "mapIndexedNotNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "mapNotNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "matches", "(CharSequence,Regex)", "generated"] + - ["kotlin.text", "StringsKt", "max", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxByOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxByOrThrow", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfWith", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOfWithOrNull", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "maxOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxOrThrow", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "maxWith", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "maxWithOrNull", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "maxWithOrThrow", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "min", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minByOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minByOrThrow", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOf", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfWith", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOfWithOrNull", "(CharSequence,Comparator,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "minOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minOrThrow", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "minWith", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "minWithOrNull", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "minWithOrThrow", "(CharSequence,Comparator)", "generated"] + - ["kotlin.text", "StringsKt", "none", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "none", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "offsetByCodePoints", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "padEnd", "(String,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "padStart", "(String,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "partition", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "partition", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "random", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "random", "(CharSequence,Random)", "generated"] + - ["kotlin.text", "StringsKt", "randomOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "randomOrNull", "(CharSequence,Random)", "generated"] + - ["kotlin.text", "StringsKt", "reduce", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceIndexedOrNull", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceOrNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRight", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightIndexedOrNull", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "reduceRightOrNull", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "regionMatches", "(CharSequence,int,CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "regionMatches", "(String,int,String,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "removeRange", "(String,IntRange)", "generated"] + - ["kotlin.text", "StringsKt", "removeRange", "(String,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "replace", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "replaceIndent", "(String,String)", "generated"] + - ["kotlin.text", "StringsKt", "replaceIndentByMargin", "(String,String,String)", "generated"] + - ["kotlin.text", "StringsKt", "replaceRange", "(String,IntRange,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "replaceRange", "(String,int,int,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "reversed", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "runningReduce", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "runningReduceIndexed", "(CharSequence,Function3)", "generated"] + - ["kotlin.text", "StringsKt", "set", "(StringBuilder,int,char)", "generated"] + - ["kotlin.text", "StringsKt", "single", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "single", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "singleOrNull", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "singleOrNull", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "slice", "(CharSequence,Iterable)", "generated"] + - ["kotlin.text", "StringsKt", "slice", "(String,Iterable)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,Regex,int)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,String[],boolean,int)", "generated"] + - ["kotlin.text", "StringsKt", "split", "(CharSequence,char[],boolean,int)", "generated"] + - ["kotlin.text", "StringsKt", "splitToSequence", "(CharSequence,Regex,int)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,CharSequence,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,CharSequence,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(CharSequence,char,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "startsWith", "(String,String,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "substring", "(CharSequence,IntRange)", "generated"] + - ["kotlin.text", "StringsKt", "substring", "(CharSequence,int,int)", "generated"] + - ["kotlin.text", "StringsKt", "sumBy", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumByDouble", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfBigDecimal", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfBigInteger", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfDouble", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfInt", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfLong", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfUInt", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "sumOfULong", "(CharSequence,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimal", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimal", "(String,MathContext)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimalOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigDecimalOrNull", "(String,MathContext)", "generated"] + - ["kotlin.text", "StringsKt", "toBigInteger", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigInteger", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toBigIntegerOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBigIntegerOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toBoolean", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanNullable", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanStrict", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toBooleanStrictOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByte", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByte", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toByteOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toByteOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toDouble", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toDoubleOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toFloat", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toFloatOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toHashSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toInt", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toInt", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toIntOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toIntOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toList", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toLong", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toLong", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toLongOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toLongOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toMutableList", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toPattern", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String,RegexOption)", "generated"] + - ["kotlin.text", "StringsKt", "toRegex", "(String,Set)", "generated"] + - ["kotlin.text", "StringsKt", "toSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toShort", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toShort", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toShortOrNull", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "toShortOrNull", "(String,int)", "generated"] + - ["kotlin.text", "StringsKt", "toSortedSet", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "StringsKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trim", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trimEnd", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "trimIndent", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimMargin", "(String,String)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "trimStart", "(String,char[])", "generated"] + - ["kotlin.text", "StringsKt", "windowed", "(CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "windowed", "(CharSequence,int,int,boolean,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "windowedSequence", "(CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "StringsKt", "windowedSequence", "(CharSequence,int,int,boolean,Function1)", "generated"] + - ["kotlin.text", "StringsKt", "withIndex", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zip", "(CharSequence,CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zip", "(CharSequence,CharSequence,Function2)", "generated"] + - ["kotlin.text", "StringsKt", "zipWithNext", "(CharSequence)", "generated"] + - ["kotlin.text", "StringsKt", "zipWithNext", "(CharSequence,Function2)", "generated"] + - ["kotlin.text", "TextHKt", "String", "(char[])", "generated"] + - ["kotlin.text", "TextHKt", "String", "(char[],int,int)", "generated"] + - ["kotlin.text", "TextHKt", "compareTo", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "concatToString", "(char[])", "generated"] + - ["kotlin.text", "TextHKt", "concatToString", "(char[],int,int)", "generated"] + - ["kotlin.text", "TextHKt", "decodeToString", "(byte[])", "generated"] + - ["kotlin.text", "TextHKt", "decodeToString", "(byte[],int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "encodeToByteArray", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "encodeToByteArray", "(String,int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "endsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "equals", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "getCASE_INSENSITIVE_ORDER", "(StringCompanionObject)", "generated"] + - ["kotlin.text", "TextHKt", "isBlank", "(CharSequence)", "generated"] + - ["kotlin.text", "TextHKt", "isHighSurrogate", "(char)", "generated"] + - ["kotlin.text", "TextHKt", "isLowSurrogate", "(char)", "generated"] + - ["kotlin.text", "TextHKt", "regionMatches", "(CharSequence,int,CharSequence,int,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "repeat", "(CharSequence,int)", "generated"] + - ["kotlin.text", "TextHKt", "replace", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replace", "(String,char,char,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replaceFirst", "(String,String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "replaceFirst", "(String,char,char,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "startsWith", "(String,String,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "startsWith", "(String,String,int,boolean)", "generated"] + - ["kotlin.text", "TextHKt", "substring", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "substring", "(String,int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toBoolean", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toByte", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toByte", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toCharArray", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toCharArray", "(String,int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toDouble", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toDoubleOrNull", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toFloat", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toFloatOrNull", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toInt", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toInt", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toLong", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toLong", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toShort", "(String)", "generated"] + - ["kotlin.text", "TextHKt", "toShort", "(String,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "TextHKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "Typography", "getAlmostEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getAmp", "()", "generated"] + - ["kotlin.text", "Typography", "getBullet", "()", "generated"] + - ["kotlin.text", "Typography", "getCent", "()", "generated"] + - ["kotlin.text", "Typography", "getCopyright", "()", "generated"] + - ["kotlin.text", "Typography", "getDagger", "()", "generated"] + - ["kotlin.text", "Typography", "getDegree", "()", "generated"] + - ["kotlin.text", "Typography", "getDollar", "()", "generated"] + - ["kotlin.text", "Typography", "getDoubleDagger", "()", "generated"] + - ["kotlin.text", "Typography", "getDoublePrime", "()", "generated"] + - ["kotlin.text", "Typography", "getEllipsis", "()", "generated"] + - ["kotlin.text", "Typography", "getEuro", "()", "generated"] + - ["kotlin.text", "Typography", "getGreater", "()", "generated"] + - ["kotlin.text", "Typography", "getGreaterOrEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getHalf", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftGuillemet", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftGuillemete", "()", "generated"] + - ["kotlin.text", "Typography", "getLeftSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLess", "()", "generated"] + - ["kotlin.text", "Typography", "getLessOrEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getLowDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getLowSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getMdash", "()", "generated"] + - ["kotlin.text", "Typography", "getMiddleDot", "()", "generated"] + - ["kotlin.text", "Typography", "getNbsp", "()", "generated"] + - ["kotlin.text", "Typography", "getNdash", "()", "generated"] + - ["kotlin.text", "Typography", "getNotEqual", "()", "generated"] + - ["kotlin.text", "Typography", "getParagraph", "()", "generated"] + - ["kotlin.text", "Typography", "getPlusMinus", "()", "generated"] + - ["kotlin.text", "Typography", "getPound", "()", "generated"] + - ["kotlin.text", "Typography", "getPrime", "()", "generated"] + - ["kotlin.text", "Typography", "getQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getRegistered", "()", "generated"] + - ["kotlin.text", "Typography", "getRightDoubleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getRightGuillemet", "()", "generated"] + - ["kotlin.text", "Typography", "getRightGuillemete", "()", "generated"] + - ["kotlin.text", "Typography", "getRightSingleQuote", "()", "generated"] + - ["kotlin.text", "Typography", "getSection", "()", "generated"] + - ["kotlin.text", "Typography", "getTimes", "()", "generated"] + - ["kotlin.text", "Typography", "getTm", "()", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(byte,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(int,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(long,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toString", "(short,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByte", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByte", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByteOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUByteOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUInt", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUInt", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUIntOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUIntOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toULong", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toULong", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toULongOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toULongOrNull", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShort", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShort", "(String,int)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShortOrNull", "(String)", "generated"] + - ["kotlin.text", "UStringsKt", "toUShortOrNull", "(String,int)", "generated"] + - ["kotlin.time", "AbstractDoubleTimeSource", "AbstractDoubleTimeSource", "(DurationUnit)", "generated"] + - ["kotlin.time", "AbstractLongTimeSource", "AbstractLongTimeSource", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "div", "(Duration)", "generated"] + - ["kotlin.time", "Duration", "equals", "(Object)", "generated"] + - ["kotlin.time", "Duration", "getInDays", "()", "generated"] + - ["kotlin.time", "Duration", "getInHours", "()", "generated"] + - ["kotlin.time", "Duration", "getInMicroseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInMinutes", "()", "generated"] + - ["kotlin.time", "Duration", "getInNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInSeconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeDays", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeHours", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMicroseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeMinutes", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "getInWholeSeconds", "()", "generated"] + - ["kotlin.time", "Duration", "hashCode", "()", "generated"] + - ["kotlin.time", "Duration", "isFinite", "()", "generated"] + - ["kotlin.time", "Duration", "isInfinite", "()", "generated"] + - ["kotlin.time", "Duration", "isNegative", "()", "generated"] + - ["kotlin.time", "Duration", "isPositive", "()", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function2)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function3)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function4)", "generated"] + - ["kotlin.time", "Duration", "toComponents", "(Function5)", "generated"] + - ["kotlin.time", "Duration", "toDouble", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toInt", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toIsoString", "()", "generated"] + - ["kotlin.time", "Duration", "toLong", "(DurationUnit)", "generated"] + - ["kotlin.time", "Duration", "toLongMilliseconds", "()", "generated"] + - ["kotlin.time", "Duration", "toLongNanoseconds", "()", "generated"] + - ["kotlin.time", "Duration", "toString", "()", "generated"] + - ["kotlin.time", "Duration", "toString", "(DurationUnit,int)", "generated"] + - ["kotlin.time", "Duration", "unaryMinus", "()", "generated"] + - ["kotlin.time", "Duration$Companion", "convert", "(double,DurationUnit,DurationUnit)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "days", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getDays", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getHours", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMicroseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMilliseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getMinutes", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getNanoseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "getSeconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "hours", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "microseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "milliseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "minutes", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "nanoseconds", "(long)", "generated"] + - ["kotlin.time", "Duration$Companion", "parse", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseIsoString", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseIsoStringOrNull", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "parseOrNull", "(String)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(double)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(int)", "generated"] + - ["kotlin.time", "Duration$Companion", "seconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getDays", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getHours", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMicroseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMilliseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getMinutes", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getNanoseconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(double)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(int)", "generated"] + - ["kotlin.time", "DurationKt", "getSeconds", "(long)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(double,DurationUnit)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(int,DurationUnit)", "generated"] + - ["kotlin.time", "DurationKt", "toDuration", "(long,DurationUnit)", "generated"] + - ["kotlin.time", "DurationUnit", "valueOf", "(String)", "generated"] + - ["kotlin.time", "DurationUnit", "values", "()", "generated"] + - ["kotlin.time", "DurationUnitKt", "toDurationUnit", "(TimeUnit)", "generated"] + - ["kotlin.time", "DurationUnitKt", "toTimeUnit", "(DurationUnit)", "generated"] + - ["kotlin.time", "ExperimentalTime", "ExperimentalTime", "()", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(Monotonic,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTime", "(TimeSource,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(Monotonic,Function0)", "generated"] + - ["kotlin.time", "MeasureTimeKt", "measureTimedValue", "(TimeSource,Function0)", "generated"] + - ["kotlin.time", "TestTimeSource", "TestTimeSource", "()", "generated"] + - ["kotlin.time", "TestTimeSource", "plusAssign", "(Duration)", "generated"] + - ["kotlin.time", "TimeMark", "elapsedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "hasNotPassedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "hasPassedNow", "()", "generated"] + - ["kotlin.time", "TimeMark", "minus", "(Duration)", "generated"] + - ["kotlin.time", "TimeMark", "plus", "(Duration)", "generated"] + - ["kotlin.time", "TimeSource", "markNow", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic", "toString", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "equals", "(Object)", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "hashCode", "()", "generated"] + - ["kotlin.time", "TimeSource$Monotonic$ValueTimeMark", "toString", "()", "generated"] + - ["kotlin.time", "TimeSourceKt", "compareTo", "(TimeMark,TimeMark)", "generated"] + - ["kotlin.time", "TimeSourceKt", "minus", "(TimeMark,TimeMark)", "generated"] + - ["kotlin.time", "TimedValue", "equals", "(Object)", "generated"] + - ["kotlin.time", "TimedValue", "hashCode", "()", "generated"] + - ["kotlin", "ArithmeticException", "ArithmeticException", "()", "generated"] + - ["kotlin", "ArithmeticException", "ArithmeticException", "(String)", "generated"] + - ["kotlin", "ArrayIntrinsicsKt", "emptyArray", "()", "generated"] + - ["kotlin", "AssertionError", "AssertionError", "()", "generated"] + - ["kotlin", "AssertionError", "AssertionError", "(Object)", "generated"] + - ["kotlin", "BuilderInference", "BuilderInference", "()", "generated"] + - ["kotlin", "CharCodeJVMKt", "Char", "(short)", "generated"] + - ["kotlin", "CharCodeKt", "Char", "(int)", "generated"] + - ["kotlin", "CharCodeKt", "Char", "(short)", "generated"] + - ["kotlin", "CharCodeKt", "getCode", "(char)", "generated"] + - ["kotlin", "ClassCastException", "ClassCastException", "()", "generated"] + - ["kotlin", "ClassCastException", "ClassCastException", "(String)", "generated"] + - ["kotlin", "Comparator", "compare", "(Object,Object)", "generated"] + - ["kotlin", "CompareToKt", "compareTo", "(Comparable,Object)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "()", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(String)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(String,Throwable)", "generated"] + - ["kotlin", "ConcurrentModificationException", "ConcurrentModificationException", "(Throwable)", "generated"] + - ["kotlin", "ContextFunctionTypeParams", "ContextFunctionTypeParams", "(int)", "generated"] + - ["kotlin", "ContextFunctionTypeParams", "count", "()", "generated"] + - ["kotlin", "DeepRecursiveKt", "invoke", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "callRecursive", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "callRecursive", "(Object)", "generated"] + - ["kotlin", "DeepRecursiveScope", "invoke", "(DeepRecursiveFunction,Object)", "generated"] + - ["kotlin", "Deprecated", "Deprecated", "(String,ReplaceWith,DeprecationLevel)", "generated"] + - ["kotlin", "Deprecated", "level", "()", "generated"] + - ["kotlin", "Deprecated", "message", "()", "generated"] + - ["kotlin", "Deprecated", "replaceWith", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "DeprecatedSinceKotlin", "(String,String,String)", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "errorSince", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "hiddenSince", "()", "generated"] + - ["kotlin", "DeprecatedSinceKotlin", "warningSince", "()", "generated"] + - ["kotlin", "DeprecationLevel", "valueOf", "(String)", "generated"] + - ["kotlin", "DeprecationLevel", "values", "()", "generated"] + - ["kotlin", "DslMarker", "DslMarker", "()", "generated"] + - ["kotlin", "Error", "Error", "()", "generated"] + - ["kotlin", "Error", "Error", "(String)", "generated"] + - ["kotlin", "Error", "Error", "(String,Throwable)", "generated"] + - ["kotlin", "Error", "Error", "(Throwable)", "generated"] + - ["kotlin", "Exception", "Exception", "()", "generated"] + - ["kotlin", "Exception", "Exception", "(String)", "generated"] + - ["kotlin", "Exception", "Exception", "(String,Throwable)", "generated"] + - ["kotlin", "Exception", "Exception", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "addSuppressed", "(Throwable,Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "getSuppressedExceptions", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "printStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsHKt", "stackTraceToString", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "addSuppressed", "(Throwable,Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "getStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "getSuppressedExceptions", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable,PrintStream)", "generated"] + - ["kotlin", "ExceptionsKt", "printStackTrace", "(Throwable,PrintWriter)", "generated"] + - ["kotlin", "ExceptionsKt", "stackTraceToString", "(Throwable)", "generated"] + - ["kotlin", "Experimental", "Experimental", "(Level)", "generated"] + - ["kotlin", "Experimental", "level", "()", "generated"] + - ["kotlin", "Experimental$Level", "valueOf", "(String)", "generated"] + - ["kotlin", "Experimental$Level", "values", "()", "generated"] + - ["kotlin", "ExperimentalMultiplatform", "ExperimentalMultiplatform", "()", "generated"] + - ["kotlin", "ExperimentalStdlibApi", "ExperimentalStdlibApi", "()", "generated"] + - ["kotlin", "ExperimentalUnsignedTypes", "ExperimentalUnsignedTypes", "()", "generated"] + - ["kotlin", "ExtensionFunctionType", "ExtensionFunctionType", "()", "generated"] + - ["kotlin", "HashCodeKt", "hashCode", "(Object)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "()", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(String)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(String,Throwable)", "generated"] + - ["kotlin", "IllegalArgumentException", "IllegalArgumentException", "(Throwable)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "()", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(String)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(String,Throwable)", "generated"] + - ["kotlin", "IllegalStateException", "IllegalStateException", "(Throwable)", "generated"] + - ["kotlin", "IndexOutOfBoundsException", "IndexOutOfBoundsException", "()", "generated"] + - ["kotlin", "IndexOutOfBoundsException", "IndexOutOfBoundsException", "(String)", "generated"] + - ["kotlin", "KotlinHKt", "fromBits", "(DoubleCompanionObject,long)", "generated"] + - ["kotlin", "KotlinHKt", "fromBits", "(FloatCompanionObject,int)", "generated"] + - ["kotlin", "KotlinHKt", "isFinite", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isFinite", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "isInfinite", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isInfinite", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "isNaN", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "isNaN", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(Function0)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(LazyThreadSafetyMode,Function0)", "generated"] + - ["kotlin", "KotlinHKt", "lazy", "(Object,Function0)", "generated"] + - ["kotlin", "KotlinHKt", "toBits", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "toBits", "(float)", "generated"] + - ["kotlin", "KotlinHKt", "toRawBits", "(double)", "generated"] + - ["kotlin", "KotlinHKt", "toRawBits", "(float)", "generated"] + - ["kotlin", "KotlinNullPointerException", "KotlinNullPointerException", "()", "generated"] + - ["kotlin", "KotlinNullPointerException", "KotlinNullPointerException", "(String)", "generated"] + - ["kotlin", "KotlinVersion", "KotlinVersion", "(int,int)", "generated"] + - ["kotlin", "KotlinVersion", "KotlinVersion", "(int,int,int)", "generated"] + - ["kotlin", "KotlinVersion", "equals", "(Object)", "generated"] + - ["kotlin", "KotlinVersion", "getMajor", "()", "generated"] + - ["kotlin", "KotlinVersion", "getMinor", "()", "generated"] + - ["kotlin", "KotlinVersion", "getPatch", "()", "generated"] + - ["kotlin", "KotlinVersion", "hashCode", "()", "generated"] + - ["kotlin", "KotlinVersion", "isAtLeast", "(int,int)", "generated"] + - ["kotlin", "KotlinVersion", "isAtLeast", "(int,int,int)", "generated"] + - ["kotlin", "KotlinVersion", "toString", "()", "generated"] + - ["kotlin", "KotlinVersion$Companion", "getMAX_COMPONENT_VALUE", "()", "generated"] + - ["kotlin", "LateinitKt", "isInitialized", "(KProperty0)", "generated"] + - ["kotlin", "Lazy", "getValue", "()", "generated"] + - ["kotlin", "Lazy", "isInitialized", "()", "generated"] + - ["kotlin", "LazyThreadSafetyMode", "valueOf", "(String)", "generated"] + - ["kotlin", "LazyThreadSafetyMode", "values", "()", "generated"] + - ["kotlin", "Metadata", "Metadata", "(int,int[],int[],String[],String[],String,String,int)", "generated"] + - ["kotlin", "Metadata", "bv", "()", "generated"] + - ["kotlin", "Metadata", "d1", "()", "generated"] + - ["kotlin", "Metadata", "d2", "()", "generated"] + - ["kotlin", "Metadata", "k", "()", "generated"] + - ["kotlin", "Metadata", "mv", "()", "generated"] + - ["kotlin", "Metadata", "pn", "()", "generated"] + - ["kotlin", "Metadata", "xi", "()", "generated"] + - ["kotlin", "Metadata", "xs", "()", "generated"] + - ["kotlin", "NoSuchElementException", "NoSuchElementException", "()", "generated"] + - ["kotlin", "NoSuchElementException", "NoSuchElementException", "(String)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "()", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(String)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(String,Throwable)", "generated"] + - ["kotlin", "NoWhenBranchMatchedException", "NoWhenBranchMatchedException", "(Throwable)", "generated"] + - ["kotlin", "NotImplementedError", "NotImplementedError", "(String)", "generated"] + - ["kotlin", "NullPointerException", "NullPointerException", "()", "generated"] + - ["kotlin", "NullPointerException", "NullPointerException", "(String)", "generated"] + - ["kotlin", "NumberFormatException", "NumberFormatException", "()", "generated"] + - ["kotlin", "NumberFormatException", "NumberFormatException", "(String)", "generated"] + - ["kotlin", "NumbersKt", "and", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countLeadingZeroBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countOneBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(int)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(long)", "generated"] + - ["kotlin", "NumbersKt", "countTrailingZeroBits", "(short)", "generated"] + - ["kotlin", "NumbersKt", "dec", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "dec", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "div", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "div", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(byte,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(int,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(long,short)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,byte)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,long)", "generated"] + - ["kotlin", "NumbersKt", "floorDiv", "(short,short)", "generated"] + - ["kotlin", "NumbersKt", "fromBits", "(DoubleCompanionObject,long)", "generated"] + - ["kotlin", "NumbersKt", "fromBits", "(FloatCompanionObject,int)", "generated"] + - ["kotlin", "NumbersKt", "inc", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "inc", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "inv", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "isFinite", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isFinite", "(float)", "generated"] + - ["kotlin", "NumbersKt", "isInfinite", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isInfinite", "(float)", "generated"] + - ["kotlin", "NumbersKt", "isNaN", "(double)", "generated"] + - ["kotlin", "NumbersKt", "isNaN", "(float)", "generated"] + - ["kotlin", "NumbersKt", "minus", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "minus", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(byte,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(double,double)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(double,float)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(float,double)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(float,float)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(int,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(long,short)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,byte)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,long)", "generated"] + - ["kotlin", "NumbersKt", "mod", "(short,short)", "generated"] + - ["kotlin", "NumbersKt", "or", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "plus", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "plus", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "rem", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "rem", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateLeft", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(byte,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(int,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(long,int)", "generated"] + - ["kotlin", "NumbersKt", "rotateRight", "(short,int)", "generated"] + - ["kotlin", "NumbersKt", "shl", "(BigInteger,int)", "generated"] + - ["kotlin", "NumbersKt", "shr", "(BigInteger,int)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(int)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(long)", "generated"] + - ["kotlin", "NumbersKt", "takeHighestOneBit", "(short)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(byte)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(int)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(long)", "generated"] + - ["kotlin", "NumbersKt", "takeLowestOneBit", "(short)", "generated"] + - ["kotlin", "NumbersKt", "times", "(BigDecimal,BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "times", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(BigInteger,int,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(double,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(float)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(float,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(int)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(int,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(long)", "generated"] + - ["kotlin", "NumbersKt", "toBigDecimal", "(long,MathContext)", "generated"] + - ["kotlin", "NumbersKt", "toBigInteger", "(int)", "generated"] + - ["kotlin", "NumbersKt", "toBigInteger", "(long)", "generated"] + - ["kotlin", "NumbersKt", "toBits", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toBits", "(float)", "generated"] + - ["kotlin", "NumbersKt", "toRawBits", "(double)", "generated"] + - ["kotlin", "NumbersKt", "toRawBits", "(float)", "generated"] + - ["kotlin", "NumbersKt", "unaryMinus", "(BigDecimal)", "generated"] + - ["kotlin", "NumbersKt", "unaryMinus", "(BigInteger)", "generated"] + - ["kotlin", "NumbersKt", "xor", "(BigInteger,BigInteger)", "generated"] + - ["kotlin", "OptIn", "OptIn", "(KClass[])", "generated"] + - ["kotlin", "OptIn", "markerClass", "()", "generated"] + - ["kotlin", "OptionalExpectation", "OptionalExpectation", "()", "generated"] + - ["kotlin", "OverloadResolutionByLambdaReturnType", "OverloadResolutionByLambdaReturnType", "()", "generated"] + - ["kotlin", "Pair", "equals", "(Object)", "generated"] + - ["kotlin", "Pair", "hashCode", "()", "generated"] + - ["kotlin", "ParameterName", "ParameterName", "(String)", "generated"] + - ["kotlin", "ParameterName", "name", "()", "generated"] + - ["kotlin", "PreconditionsKt", "assert", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "assert", "(boolean,Function0)", "generated"] + - ["kotlin", "PreconditionsKt", "check", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "check", "(boolean,Function0)", "generated"] + - ["kotlin", "PreconditionsKt", "error", "(Object)", "generated"] + - ["kotlin", "PreconditionsKt", "require", "(boolean)", "generated"] + - ["kotlin", "PreconditionsKt", "require", "(boolean,Function0)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "getValue", "(KProperty0,Object,KProperty)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "getValue", "(KProperty1,Object,KProperty)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "setValue", "(KMutableProperty0,Object,KProperty,Object)", "generated"] + - ["kotlin", "PropertyReferenceDelegatesKt", "setValue", "(KMutableProperty1,Object,KProperty,Object)", "generated"] + - ["kotlin", "PublishedApi", "PublishedApi", "()", "generated"] + - ["kotlin", "ReplaceWith", "ReplaceWith", "(String,String[])", "generated"] + - ["kotlin", "ReplaceWith", "expression", "()", "generated"] + - ["kotlin", "ReplaceWith", "imports", "()", "generated"] + - ["kotlin", "RequiresOptIn", "RequiresOptIn", "(String,Level)", "generated"] + - ["kotlin", "RequiresOptIn", "level", "()", "generated"] + - ["kotlin", "RequiresOptIn", "message", "()", "generated"] + - ["kotlin", "RequiresOptIn$Level", "valueOf", "(String)", "generated"] + - ["kotlin", "RequiresOptIn$Level", "values", "()", "generated"] + - ["kotlin", "Result", "equals", "(Object)", "generated"] + - ["kotlin", "Result", "hashCode", "()", "generated"] + - ["kotlin", "Result", "isFailure", "()", "generated"] + - ["kotlin", "Result", "isSuccess", "()", "generated"] + - ["kotlin", "ResultKt", "runCatching", "(Function0)", "generated"] + - ["kotlin", "ResultKt", "runCatching", "(Object,Function1)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "()", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(String)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(String,Throwable)", "generated"] + - ["kotlin", "RuntimeException", "RuntimeException", "(Throwable)", "generated"] + - ["kotlin", "SinceKotlin", "SinceKotlin", "(String)", "generated"] + - ["kotlin", "SinceKotlin", "version", "()", "generated"] + - ["kotlin", "StandardKt", "TODO", "()", "generated"] + - ["kotlin", "StandardKt", "TODO", "(String)", "generated"] + - ["kotlin", "StandardKt", "repeat", "(int,Function1)", "generated"] + - ["kotlin", "StandardKt", "run", "(Function0)", "generated"] + - ["kotlin", "StandardKt", "synchronized", "(Object,Function0)", "generated"] + - ["kotlin", "Suppress", "Suppress", "(String[])", "generated"] + - ["kotlin", "Suppress", "names", "()", "generated"] + - ["kotlin", "Throws", "Throws", "(KClass[])", "generated"] + - ["kotlin", "Throws", "exceptionClasses", "()", "generated"] + - ["kotlin", "Triple", "equals", "(Object)", "generated"] + - ["kotlin", "Triple", "hashCode", "()", "generated"] + - ["kotlin", "TypeCastException", "TypeCastException", "()", "generated"] + - ["kotlin", "TypeCastException", "TypeCastException", "(String)", "generated"] + - ["kotlin", "UByte", "and", "(byte)", "generated"] + - ["kotlin", "UByte", "compareTo", "(byte)", "generated"] + - ["kotlin", "UByte", "compareTo", "(int)", "generated"] + - ["kotlin", "UByte", "compareTo", "(long)", "generated"] + - ["kotlin", "UByte", "compareTo", "(short)", "generated"] + - ["kotlin", "UByte", "dec", "()", "generated"] + - ["kotlin", "UByte", "div", "(byte)", "generated"] + - ["kotlin", "UByte", "div", "(int)", "generated"] + - ["kotlin", "UByte", "div", "(long)", "generated"] + - ["kotlin", "UByte", "div", "(short)", "generated"] + - ["kotlin", "UByte", "equals", "(Object)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(int)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(long)", "generated"] + - ["kotlin", "UByte", "floorDiv", "(short)", "generated"] + - ["kotlin", "UByte", "hashCode", "()", "generated"] + - ["kotlin", "UByte", "inc", "()", "generated"] + - ["kotlin", "UByte", "inv", "()", "generated"] + - ["kotlin", "UByte", "minus", "(byte)", "generated"] + - ["kotlin", "UByte", "minus", "(int)", "generated"] + - ["kotlin", "UByte", "minus", "(long)", "generated"] + - ["kotlin", "UByte", "minus", "(short)", "generated"] + - ["kotlin", "UByte", "mod", "(byte)", "generated"] + - ["kotlin", "UByte", "mod", "(int)", "generated"] + - ["kotlin", "UByte", "mod", "(long)", "generated"] + - ["kotlin", "UByte", "mod", "(short)", "generated"] + - ["kotlin", "UByte", "or", "(byte)", "generated"] + - ["kotlin", "UByte", "plus", "(byte)", "generated"] + - ["kotlin", "UByte", "plus", "(int)", "generated"] + - ["kotlin", "UByte", "plus", "(long)", "generated"] + - ["kotlin", "UByte", "plus", "(short)", "generated"] + - ["kotlin", "UByte", "rangeTo", "(byte)", "generated"] + - ["kotlin", "UByte", "rem", "(byte)", "generated"] + - ["kotlin", "UByte", "rem", "(int)", "generated"] + - ["kotlin", "UByte", "rem", "(long)", "generated"] + - ["kotlin", "UByte", "rem", "(short)", "generated"] + - ["kotlin", "UByte", "times", "(byte)", "generated"] + - ["kotlin", "UByte", "times", "(int)", "generated"] + - ["kotlin", "UByte", "times", "(long)", "generated"] + - ["kotlin", "UByte", "times", "(short)", "generated"] + - ["kotlin", "UByte", "toByte", "()", "generated"] + - ["kotlin", "UByte", "toDouble", "()", "generated"] + - ["kotlin", "UByte", "toFloat", "()", "generated"] + - ["kotlin", "UByte", "toInt", "()", "generated"] + - ["kotlin", "UByte", "toLong", "()", "generated"] + - ["kotlin", "UByte", "toShort", "()", "generated"] + - ["kotlin", "UByte", "toString", "()", "generated"] + - ["kotlin", "UByte", "toUInt", "()", "generated"] + - ["kotlin", "UByte", "toULong", "()", "generated"] + - ["kotlin", "UByte", "toUShort", "()", "generated"] + - ["kotlin", "UByte", "xor", "(byte)", "generated"] + - ["kotlin", "UByte$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UByte$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UByte$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UByte$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UByteArray", "UByteArray", "(int)", "generated"] + - ["kotlin", "UByteArray", "equals", "(Object)", "generated"] + - ["kotlin", "UByteArray", "get", "(int)", "generated"] + - ["kotlin", "UByteArray", "hashCode", "()", "generated"] + - ["kotlin", "UByteArray", "set", "(int,byte)", "generated"] + - ["kotlin", "UByteArray", "toString", "()", "generated"] + - ["kotlin", "UByteArrayKt", "UByteArray", "(int,Function1)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(byte)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(int)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(long)", "generated"] + - ["kotlin", "UByteKt", "toUByte", "(short)", "generated"] + - ["kotlin", "UInt", "and", "(int)", "generated"] + - ["kotlin", "UInt", "compareTo", "(byte)", "generated"] + - ["kotlin", "UInt", "compareTo", "(int)", "generated"] + - ["kotlin", "UInt", "compareTo", "(long)", "generated"] + - ["kotlin", "UInt", "compareTo", "(short)", "generated"] + - ["kotlin", "UInt", "dec", "()", "generated"] + - ["kotlin", "UInt", "div", "(byte)", "generated"] + - ["kotlin", "UInt", "div", "(int)", "generated"] + - ["kotlin", "UInt", "div", "(long)", "generated"] + - ["kotlin", "UInt", "div", "(short)", "generated"] + - ["kotlin", "UInt", "equals", "(Object)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(int)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(long)", "generated"] + - ["kotlin", "UInt", "floorDiv", "(short)", "generated"] + - ["kotlin", "UInt", "hashCode", "()", "generated"] + - ["kotlin", "UInt", "inc", "()", "generated"] + - ["kotlin", "UInt", "inv", "()", "generated"] + - ["kotlin", "UInt", "minus", "(byte)", "generated"] + - ["kotlin", "UInt", "minus", "(int)", "generated"] + - ["kotlin", "UInt", "minus", "(long)", "generated"] + - ["kotlin", "UInt", "minus", "(short)", "generated"] + - ["kotlin", "UInt", "mod", "(byte)", "generated"] + - ["kotlin", "UInt", "mod", "(int)", "generated"] + - ["kotlin", "UInt", "mod", "(long)", "generated"] + - ["kotlin", "UInt", "mod", "(short)", "generated"] + - ["kotlin", "UInt", "or", "(int)", "generated"] + - ["kotlin", "UInt", "plus", "(byte)", "generated"] + - ["kotlin", "UInt", "plus", "(int)", "generated"] + - ["kotlin", "UInt", "plus", "(long)", "generated"] + - ["kotlin", "UInt", "plus", "(short)", "generated"] + - ["kotlin", "UInt", "rangeTo", "(int)", "generated"] + - ["kotlin", "UInt", "rem", "(byte)", "generated"] + - ["kotlin", "UInt", "rem", "(int)", "generated"] + - ["kotlin", "UInt", "rem", "(long)", "generated"] + - ["kotlin", "UInt", "rem", "(short)", "generated"] + - ["kotlin", "UInt", "shl", "(int)", "generated"] + - ["kotlin", "UInt", "shr", "(int)", "generated"] + - ["kotlin", "UInt", "times", "(byte)", "generated"] + - ["kotlin", "UInt", "times", "(int)", "generated"] + - ["kotlin", "UInt", "times", "(long)", "generated"] + - ["kotlin", "UInt", "times", "(short)", "generated"] + - ["kotlin", "UInt", "toByte", "()", "generated"] + - ["kotlin", "UInt", "toDouble", "()", "generated"] + - ["kotlin", "UInt", "toFloat", "()", "generated"] + - ["kotlin", "UInt", "toInt", "()", "generated"] + - ["kotlin", "UInt", "toLong", "()", "generated"] + - ["kotlin", "UInt", "toShort", "()", "generated"] + - ["kotlin", "UInt", "toString", "()", "generated"] + - ["kotlin", "UInt", "toUByte", "()", "generated"] + - ["kotlin", "UInt", "toULong", "()", "generated"] + - ["kotlin", "UInt", "toUShort", "()", "generated"] + - ["kotlin", "UInt", "xor", "(int)", "generated"] + - ["kotlin", "UInt$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UInt$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UInt$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UInt$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UIntArray", "UIntArray", "(int)", "generated"] + - ["kotlin", "UIntArray", "equals", "(Object)", "generated"] + - ["kotlin", "UIntArray", "get", "(int)", "generated"] + - ["kotlin", "UIntArray", "hashCode", "()", "generated"] + - ["kotlin", "UIntArray", "set", "(int,int)", "generated"] + - ["kotlin", "UIntArray", "toString", "()", "generated"] + - ["kotlin", "UIntArrayKt", "UIntArray", "(int,Function1)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(byte)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(double)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(float)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(int)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(long)", "generated"] + - ["kotlin", "UIntKt", "toUInt", "(short)", "generated"] + - ["kotlin", "ULong", "and", "(long)", "generated"] + - ["kotlin", "ULong", "compareTo", "(byte)", "generated"] + - ["kotlin", "ULong", "compareTo", "(int)", "generated"] + - ["kotlin", "ULong", "compareTo", "(long)", "generated"] + - ["kotlin", "ULong", "compareTo", "(short)", "generated"] + - ["kotlin", "ULong", "dec", "()", "generated"] + - ["kotlin", "ULong", "div", "(byte)", "generated"] + - ["kotlin", "ULong", "div", "(int)", "generated"] + - ["kotlin", "ULong", "div", "(long)", "generated"] + - ["kotlin", "ULong", "div", "(short)", "generated"] + - ["kotlin", "ULong", "equals", "(Object)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(byte)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(int)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(long)", "generated"] + - ["kotlin", "ULong", "floorDiv", "(short)", "generated"] + - ["kotlin", "ULong", "hashCode", "()", "generated"] + - ["kotlin", "ULong", "inc", "()", "generated"] + - ["kotlin", "ULong", "inv", "()", "generated"] + - ["kotlin", "ULong", "minus", "(byte)", "generated"] + - ["kotlin", "ULong", "minus", "(int)", "generated"] + - ["kotlin", "ULong", "minus", "(long)", "generated"] + - ["kotlin", "ULong", "minus", "(short)", "generated"] + - ["kotlin", "ULong", "mod", "(byte)", "generated"] + - ["kotlin", "ULong", "mod", "(int)", "generated"] + - ["kotlin", "ULong", "mod", "(long)", "generated"] + - ["kotlin", "ULong", "mod", "(short)", "generated"] + - ["kotlin", "ULong", "or", "(long)", "generated"] + - ["kotlin", "ULong", "plus", "(byte)", "generated"] + - ["kotlin", "ULong", "plus", "(int)", "generated"] + - ["kotlin", "ULong", "plus", "(long)", "generated"] + - ["kotlin", "ULong", "plus", "(short)", "generated"] + - ["kotlin", "ULong", "rangeTo", "(long)", "generated"] + - ["kotlin", "ULong", "rem", "(byte)", "generated"] + - ["kotlin", "ULong", "rem", "(int)", "generated"] + - ["kotlin", "ULong", "rem", "(long)", "generated"] + - ["kotlin", "ULong", "rem", "(short)", "generated"] + - ["kotlin", "ULong", "shl", "(int)", "generated"] + - ["kotlin", "ULong", "shr", "(int)", "generated"] + - ["kotlin", "ULong", "times", "(byte)", "generated"] + - ["kotlin", "ULong", "times", "(int)", "generated"] + - ["kotlin", "ULong", "times", "(long)", "generated"] + - ["kotlin", "ULong", "times", "(short)", "generated"] + - ["kotlin", "ULong", "toByte", "()", "generated"] + - ["kotlin", "ULong", "toDouble", "()", "generated"] + - ["kotlin", "ULong", "toFloat", "()", "generated"] + - ["kotlin", "ULong", "toInt", "()", "generated"] + - ["kotlin", "ULong", "toLong", "()", "generated"] + - ["kotlin", "ULong", "toShort", "()", "generated"] + - ["kotlin", "ULong", "toString", "()", "generated"] + - ["kotlin", "ULong", "toUByte", "()", "generated"] + - ["kotlin", "ULong", "toUInt", "()", "generated"] + - ["kotlin", "ULong", "toUShort", "()", "generated"] + - ["kotlin", "ULong", "xor", "(long)", "generated"] + - ["kotlin", "ULong$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "ULong$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "ULong$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "ULong$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "ULongArray", "ULongArray", "(int)", "generated"] + - ["kotlin", "ULongArray", "equals", "(Object)", "generated"] + - ["kotlin", "ULongArray", "get", "(int)", "generated"] + - ["kotlin", "ULongArray", "hashCode", "()", "generated"] + - ["kotlin", "ULongArray", "set", "(int,long)", "generated"] + - ["kotlin", "ULongArray", "toString", "()", "generated"] + - ["kotlin", "ULongArrayKt", "ULongArray", "(int,Function1)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(byte)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(double)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(float)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(int)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(long)", "generated"] + - ["kotlin", "ULongKt", "toULong", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countLeadingZeroBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countOneBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "countTrailingZeroBits", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(byte,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(int,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(long,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateLeft", "(short,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(byte,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(int,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(long,int)", "generated"] + - ["kotlin", "UNumbersKt", "rotateRight", "(short,int)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "takeHighestOneBit", "(short)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(byte)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(int)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(long)", "generated"] + - ["kotlin", "UNumbersKt", "takeLowestOneBit", "(short)", "generated"] + - ["kotlin", "UShort", "and", "(short)", "generated"] + - ["kotlin", "UShort", "compareTo", "(byte)", "generated"] + - ["kotlin", "UShort", "compareTo", "(int)", "generated"] + - ["kotlin", "UShort", "compareTo", "(long)", "generated"] + - ["kotlin", "UShort", "compareTo", "(short)", "generated"] + - ["kotlin", "UShort", "dec", "()", "generated"] + - ["kotlin", "UShort", "div", "(byte)", "generated"] + - ["kotlin", "UShort", "div", "(int)", "generated"] + - ["kotlin", "UShort", "div", "(long)", "generated"] + - ["kotlin", "UShort", "div", "(short)", "generated"] + - ["kotlin", "UShort", "equals", "(Object)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(byte)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(int)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(long)", "generated"] + - ["kotlin", "UShort", "floorDiv", "(short)", "generated"] + - ["kotlin", "UShort", "hashCode", "()", "generated"] + - ["kotlin", "UShort", "inc", "()", "generated"] + - ["kotlin", "UShort", "inv", "()", "generated"] + - ["kotlin", "UShort", "minus", "(byte)", "generated"] + - ["kotlin", "UShort", "minus", "(int)", "generated"] + - ["kotlin", "UShort", "minus", "(long)", "generated"] + - ["kotlin", "UShort", "minus", "(short)", "generated"] + - ["kotlin", "UShort", "mod", "(byte)", "generated"] + - ["kotlin", "UShort", "mod", "(int)", "generated"] + - ["kotlin", "UShort", "mod", "(long)", "generated"] + - ["kotlin", "UShort", "mod", "(short)", "generated"] + - ["kotlin", "UShort", "or", "(short)", "generated"] + - ["kotlin", "UShort", "plus", "(byte)", "generated"] + - ["kotlin", "UShort", "plus", "(int)", "generated"] + - ["kotlin", "UShort", "plus", "(long)", "generated"] + - ["kotlin", "UShort", "plus", "(short)", "generated"] + - ["kotlin", "UShort", "rangeTo", "(short)", "generated"] + - ["kotlin", "UShort", "rem", "(byte)", "generated"] + - ["kotlin", "UShort", "rem", "(int)", "generated"] + - ["kotlin", "UShort", "rem", "(long)", "generated"] + - ["kotlin", "UShort", "rem", "(short)", "generated"] + - ["kotlin", "UShort", "times", "(byte)", "generated"] + - ["kotlin", "UShort", "times", "(int)", "generated"] + - ["kotlin", "UShort", "times", "(long)", "generated"] + - ["kotlin", "UShort", "times", "(short)", "generated"] + - ["kotlin", "UShort", "toByte", "()", "generated"] + - ["kotlin", "UShort", "toDouble", "()", "generated"] + - ["kotlin", "UShort", "toFloat", "()", "generated"] + - ["kotlin", "UShort", "toInt", "()", "generated"] + - ["kotlin", "UShort", "toLong", "()", "generated"] + - ["kotlin", "UShort", "toShort", "()", "generated"] + - ["kotlin", "UShort", "toString", "()", "generated"] + - ["kotlin", "UShort", "toUByte", "()", "generated"] + - ["kotlin", "UShort", "toUInt", "()", "generated"] + - ["kotlin", "UShort", "toULong", "()", "generated"] + - ["kotlin", "UShort", "xor", "(short)", "generated"] + - ["kotlin", "UShort$Companion", "getMAX_VALUE", "()", "generated"] + - ["kotlin", "UShort$Companion", "getMIN_VALUE", "()", "generated"] + - ["kotlin", "UShort$Companion", "getSIZE_BITS", "()", "generated"] + - ["kotlin", "UShort$Companion", "getSIZE_BYTES", "()", "generated"] + - ["kotlin", "UShortArray", "UShortArray", "(int)", "generated"] + - ["kotlin", "UShortArray", "equals", "(Object)", "generated"] + - ["kotlin", "UShortArray", "get", "(int)", "generated"] + - ["kotlin", "UShortArray", "hashCode", "()", "generated"] + - ["kotlin", "UShortArray", "set", "(int,short)", "generated"] + - ["kotlin", "UShortArray", "toString", "()", "generated"] + - ["kotlin", "UShortArrayKt", "UShortArray", "(int,Function1)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(byte)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(int)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(long)", "generated"] + - ["kotlin", "UShortKt", "toUShort", "(short)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "()", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(String)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(String,Throwable)", "generated"] + - ["kotlin", "UninitializedPropertyAccessException", "UninitializedPropertyAccessException", "(Throwable)", "generated"] + - ["kotlin", "Unit", "toString", "()", "generated"] + - ["kotlin", "UnsafeVariance", "UnsafeVariance", "()", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "()", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(String)", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(String,Throwable)", "generated"] + - ["kotlin", "UnsupportedOperationException", "UnsupportedOperationException", "(Throwable)", "generated"] + - ["kotlin", "UseExperimental", "UseExperimental", "(KClass[])", "generated"] + - ["kotlin", "UseExperimental", "markerClass", "()", "generated"] diff --git a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml new file mode 100644 index 00000000000..c2b6697d812 --- /dev/null +++ b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml @@ -0,0 +1,1432 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models for the org.apache.commons.io framework. + +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.io.file", "PathFilter", true, "accept", "(Path,BasicFileAttributes)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "newOutputStream", "(Path,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filter", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterList", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterSet", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", true, "getRandomAccess", "(String)", "", "Argument[-1]", "create-file", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectoryToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(Iterable,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectory", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectoryToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "newOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "touch", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[])", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,boolean)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[1]", "create-file", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,OutputStream)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URI)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,Charset)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,String)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,Charset)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,String)", "", "Argument[0]", "open-url", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(File)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(Path)", "", "Argument[0]", "create-file", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(String)", "", "Argument[0]", "create-file", "generated"] + + + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.io.charset", "CharsetDecoders", true, "toCharsetDecoder", "(CharsetDecoder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.charset", "CharsetEncoders", true, "toCharsetEncoder", "(CharsetEncoder)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "CompositeFileComparator", "(Comparator[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "CompositeFileComparator", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.comparator", "CompositeFileComparator", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(URI)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", true, "getFileSystemProvider", "(URL)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "AccumulatorPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "getDirList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "getFileList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withBigIntegerCounters", "(PathFilter,PathFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withBigIntegerCounters", "(PathFilter,PathFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withLongCounters", "(PathFilter,PathFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", true, "withLongCounters", "(PathFilter,PathFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", true, "CleaningPathVisitor", "(PathCounters,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[2].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,Path,Path,CopyOption[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[3].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[4].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "CopyDirectoryVisitor", "(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[])", "", "Argument[5].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getCopyOptions", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getSourceDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CopyDirectoryVisitor", true, "getTargetDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getByteCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getDirectoryCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", true, "getFileCounter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "CountingPathVisitor", "(PathCounters,PathFilter,PathFilter)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", true, "getPathCounters", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,DeleteOption[],String[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,LinkOption[],DeleteOption[],String[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,String[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", true, "DeletingPathVisitor", "(PathCounters,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DirectoryStreamFilter", true, "DirectoryStreamFilter", "(PathFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.file", "DirectoryStreamFilter", true, "getPathFilter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "setReadOnly", "(Path,boolean,LinkOption[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,Path)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,Path,Set,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,String,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "visitFileTree", "(FileVisitor,URI)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "AgeFileFilter", "(Instant)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "AgeFileFilter", "(Instant,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "AndFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "addFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "addFileFilter", "(IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "getFileFilters", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", true, "setFileFilters", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "DelegateFileFilter", "(FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "DelegateFileFilter", "(FilenameFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "DelegateFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileEqualsFileFilter", true, "FileEqualsFileFilter", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "and", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "andFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "andFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "asFileFilter", "(FileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "asFileFilter", "(FilenameFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(String,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "magicNumberFileFilter", "(byte[],long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeCVSAware", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeDirectoryOnly", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeFileOnly", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "makeSVNAware", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "nameFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "nameFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "notFileFilter", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "or", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "orFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "orFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "prefixFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "prefixFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "suffixFileFilter", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "suffixFileFilter", "(String,IOCase)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "toList", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "and", "(IOFileFilter)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "and", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "negate", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "or", "(IOFileFilter)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", true, "or", "(IOFileFilter)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(String,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "MagicNumberFileFilter", "(byte[],long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "MagicNumberFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "NameFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NameFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NotFileFilter", true, "NotFileFilter", "(IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "NotFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter,IOFileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "OrFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "addFileFilter", "(IOFileFilter[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PathEqualsFileFilter", true, "PathEqualsFileFilter", "(Path)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PathVisitorFileFilter", true, "PathVisitorFileFilter", "(PathVisitor)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "PrefixFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "PrefixFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern,Function)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "RegexFileFilter", "(Pattern,Function)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "SuffixFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "SuffixFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(List,IOCase)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "WildcardFileFilter", "(String[],IOCase)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFileFilter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.filefilter", "WildcardFilter", true, "WildcardFilter", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularBufferInputStream", true, "CircularBufferInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularBufferInputStream", true, "CircularBufferInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", true, "PeekableInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", true, "PeekableInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "BOMInputStream", "(InputStream,ByteOrderMark[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "BOMInputStream", "(InputStream,boolean,ByteOrderMark[])", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "getBOM", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", true, "getBOMCharsetName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", true, "BoundedInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", true, "BoundedInputStream", "(InputStream,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BoundedReader", true, "BoundedReader", "(Reader,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", true, "BrokenInputStream", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", true, "BrokenReader", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "CharSequenceReader", "(CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CharSequenceReader", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "CharacterFilterReader", true, "CharacterFilterReader", "(Reader,IntPredicate)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CircularInputStream", true, "CircularInputStream", "(byte[],long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ClassLoaderObjectInputStream", true, "ClassLoaderObjectInputStream", "(ClassLoader,InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ClassLoaderObjectInputStream", true, "ClassLoaderObjectInputStream", "(ClassLoader,InputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "CloseShieldInputStream", true, "wrap", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "InfiniteCircularInputStream", true, "InfiniteCircularInputStream", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream$MessageDigestMaintainingObserver", true, "MessageDigestMaintainingObserver", "(MessageDigest)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", true, "MessageDigestCalculatingInputStream", "(InputStream,MessageDigest)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", true, "getMessageDigest", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "ObservableInputStream", "(InputStream,Observer[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "add", "(Observer)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", true, "getObservers", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "RandomAccessFileInputStream", "(RandomAccessFile)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "RandomAccessFileInputStream", "(RandomAccessFile,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", true, "getRandomAccessFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int,ExecutorService)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReadAheadInputStream", true, "ReadAheadInputStream", "(InputStream,int,ExecutorService)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,Charset)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,Charset,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,CharsetEncoder,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReaderInputStream", true, "ReaderInputStream", "(Reader,String,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "readLines", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", true, "toString", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "SequenceReader", true, "SequenceReader", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "SequenceReader", true, "SequenceReader", "(Reader[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(File,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(File,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Path,TailerListener)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Path,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Tailable,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "Builder", "(Tailable,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "build", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withBufferSize", "(int)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withCharset", "(Charset)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withDelayDuration", "(Duration)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withDelayDuration", "(Duration)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withReOpen", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withStartThread", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer$Builder", true, "withTailFromEnd", "(boolean)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "Tailer", "(File,TailerListener,long,boolean,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,Charset,TailerListener,long,boolean,boolean,int)", "", "Argument[2]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "create", "(File,TailerListener,long,boolean,int)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getDelayDuration", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "Tailer", true, "getTailable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeInputStream", true, "TeeInputStream", "(InputStream,OutputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeInputStream", true, "TeeInputStream", "(InputStream,OutputStream,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeReader", true, "TeeReader", "(Reader,Writer)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TeeReader", true, "TeeReader", "(Reader,Writer,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "getCloseInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "getOpenInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "UncheckedBufferedReader", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "UncheckedBufferedReader", "(Reader,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedBufferedReader", true, "on", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterInputStream", true, "on", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "UnixLineEndingInputStream", true, "UnixLineEndingInputStream", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[],int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "UnsynchronizedByteArrayInputStream", true, "UnsynchronizedByteArrayInputStream", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "WindowsLineEndingInputStream", true, "WindowsLineEndingInputStream", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,String,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(InputStream,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URLConnection,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "getDefaultEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "getEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "XmlStreamReaderException", "(String,String,String,String,String,String)", "", "Argument[5]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getBomEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getContentTypeEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getContentTypeMime", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getXmlEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReaderException", true, "getXmlGuessEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "FileAlterationMonitor", "(long,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "FileAlterationMonitor", "(long,FileAlterationObserver[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "addObserver", "(FileAlterationObserver)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "getObservers", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", false, "setThreadFactory", "(ThreadFactory)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(File,FileFilter,IOCase)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter,IOCase)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "FileAlterationObserver", "(String,FileFilter,IOCase)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "addListener", "(FileAlterationListener)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getDirectory", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getFileFilter", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "getListeners", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(FileEntry,File)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "FileEntry", "(FileEntry,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getChildren", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getLastModifiedFileTime", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "getParent", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "newChildInstance", "(File)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "newChildInstance", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setChildren", "(FileEntry[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setLastModified", "(FileTime)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", true, "setName", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "toString", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "write", "(InputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "write", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableOutputStream", true, "AppendableOutputStream", "(Appendable)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableOutputStream", true, "getAppendable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableWriter", true, "AppendableWriter", "(Appendable)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "AppendableWriter", true, "getAppendable", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", true, "BrokenOutputStream", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", true, "BrokenWriter", "(Supplier)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "CloseShieldOutputStream", true, "CloseShieldOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "CloseShieldOutputStream", true, "wrap", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", true, "CountingOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,String,String,File)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "DeferredFileOutputStream", "(int,int,String,String,File)", "", "Argument[4]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "getData", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[3]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyCollectionWriter", true, "ProxyCollectionWriter", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyCollectionWriter", true, "ProxyCollectionWriter", "(Writer[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ProxyOutputStream", true, "ProxyOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "StringBuilderWriter", "(StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "getBuilder", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", true, "TaggedOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeOutputStream", true, "TeeOutputStream", "(OutputStream,OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeOutputStream", true, "TeeOutputStream", "(OutputStream,OutputStream)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeWriter", true, "TeeWriter", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "TeeWriter", true, "TeeWriter", "(Writer[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", true, "ThresholdingOutputStream", "(int,IOConsumer,IOFunction)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", true, "ThresholdingOutputStream", "(int,IOConsumer,IOFunction)", "", "Argument[2]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedAppendable", true, "on", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterOutputStream", true, "UncheckedFilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterOutputStream", true, "on", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,Charset)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,Charset,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,CharsetDecoder,int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "WriterOutputStream", true, "WriterOutputStream", "(Writer,String,int,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream,String)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(OutputStream,String)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "getDefaultEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "getEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "ValidatingObjectInputStream", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(ClassNameMatcher)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(ClassNameMatcher)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(Class[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(Pattern)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "accept", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(ClassNameMatcher)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(ClassNameMatcher)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(Class[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(Pattern)", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io.serialization", "ValidatingObjectInputStream", true, "reject", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "ByteOrderMark", "(String,int[])", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "getCharsetName", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(InputStream,Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "CopyUtils", true, "copy", "(byte[],Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "CancelException", "(File,int)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "CancelException", "(String,File,int)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", true, "getFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", true, "getDeleteFailures", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", true, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileSystem", false, "normalizeSeparators", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileSystem", false, "toLegalFileName", "(String,char)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "checksum", "(File,Checksum)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "convertFileCollectionToFileArray", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "delete", "(File)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(File,String[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(File,String[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "getFile", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FileUtils", true, "toURLs", "(File[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "concat", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "concat", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getBaseName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getFullPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getFullPathNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPathNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "getPrefix", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalize", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalizeNoEndSeparator", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "normalizeNoEndSeparator", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "removeExtension", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToSystem", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToUnix", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "FilenameUtils", true, "separatorsToWindows", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "IOExceptionList", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "IOExceptionList", "(String,List)", "", "Argument[1].Element", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCause", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCauseList", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOExceptionList", true, "getCauseList", "(Class)", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(OutputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Writer)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "buffer", "(Writer,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,OutputStream,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer,Charset)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(InputStream,Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Appendable,CharBuffer)", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,byte[])", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[0]", "Argument[4]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[4]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(InputStream,OutputStream,long,long,byte[])", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[0]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[2]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,char[])", "", "Argument[2]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[0]", "Argument[4]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[4]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "copyLarge", "(Reader,Writer,long,long,char[])", "", "Argument[4]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "lineIterator", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(InputStream,byte[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(ReadableByteChannel,ByteBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "read", "(Reader,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,byte[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(ReadableByteChannel,ByteBuffer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[])", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[])", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[],int,int)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readFully", "(Reader,char[],int,int)", "", "Argument[1]", "Argument[0]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "readLines", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toBufferedReader", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toBufferedReader", "(Reader,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(InputStream,int)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(InputStream,long)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toCharArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toInputStream", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream,Charset)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(byte[],String)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(CharSequence,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(StringBuffer,Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer,Charset)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(byte[],Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "write", "(char[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeChunked", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeChunked", "(char[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream,Charset)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,OutputStream,String)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writeLines", "(Collection,String,Writer)", "", "Argument[1]", "Argument[2]", "taint", "generated"] + - ["org.apache.commons.io", "IOUtils", true, "writer", "(Appendable)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "LineIterator", true, "LineIterator", "(Reader)", "", "Argument[0]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "LineIterator", true, "nextLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "TaggedIOException", true, "TaggedIOException", "(IOException,Serializable)", "", "Argument[1]", "Argument[-1]", "taint", "generated"] + - ["org.apache.commons.io", "TaggedIOException", true, "getTag", "()", "", "Argument[-1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "UncheckedIO", true, "apply", "(IOFunction,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + - ["org.apache.commons.io", "UncheckedIO", true, "apply", "(IOTriFunction,Object,Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "generated"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["org.apache.commons.io.charset", "CharsetDecoders", "CharsetDecoders", "()", "generated"] + - ["org.apache.commons.io.charset", "CharsetEncoders", "CharsetEncoders", "()", "generated"] + - ["org.apache.commons.io.comparator", "DefaultFileComparator", "DefaultFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "DirectoryFileComparator", "DirectoryFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "ExtensionFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "ExtensionFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "ExtensionFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "LastModifiedFileComparator", "LastModifiedFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "NameFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "NameFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "NameFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "PathFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "PathFileComparator", "(IOCase)", "generated"] + - ["org.apache.commons.io.comparator", "PathFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "SizeFileComparator", "()", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "SizeFileComparator", "(boolean)", "generated"] + - ["org.apache.commons.io.comparator", "SizeFileComparator", "toString", "()", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusMillis", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusNanos", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "minusSeconds", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "now", "()", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "ntfsTimeToDate", "(long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "ntfsTimeToFileTime", "(long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusMillis", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusNanos", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "plusSeconds", "(FileTime,long)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "setLastModifiedTime", "(Path)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toDate", "(FileTime)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toFileTime", "(Date)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toNtfsTime", "(Date)", "generated"] + - ["org.apache.commons.io.file.attribute", "FileTimes", "toNtfsTime", "(FileTime)", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", "getFileSystemProvider", "(Path)", "generated"] + - ["org.apache.commons.io.file.spi", "FileSystemProviders", "installed", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "AccumulatorPathVisitor", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "relativizeDirectories", "(Path,boolean,Comparator)", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "relativizeFiles", "(Path,boolean,Comparator)", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "AccumulatorPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CleaningPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "add", "(long)", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "get", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "getBigInteger", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "getLong", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "increment", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$Counter", "reset", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getByteCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getDirectoryCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "getFileCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters$PathCounters", "reset", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "Counters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "bigIntegerCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "bigIntegerPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "longCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "longPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "noopCounter", "()", "generated"] + - ["org.apache.commons.io.file", "Counters", "noopPathCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "toString", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "CountingPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", "withBigIntegerCounters", "()", "generated"] + - ["org.apache.commons.io.file", "DeletingPathVisitor", "withLongCounters", "()", "generated"] + - ["org.apache.commons.io.file", "NoopPathVisitor", "NoopPathVisitor", "()", "generated"] + - ["org.apache.commons.io.file", "PathFilter", "accept", "(Path,BasicFileAttributes)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "cleanDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "cleanDirectory", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "copyDirectory", "(Path,Path,CopyOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "copyFileToDirectory", "(Path,Path,CopyOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "countDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "countDirectoryAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "createParentDirectories", "(Path,FileAttribute[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "createParentDirectories", "(Path,LinkOption,FileAttribute[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "current", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "delete", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteDirectory", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path,DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "deleteFile", "(Path,LinkOption[],DeleteOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryAndFileContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryAndFileContentEquals", "(Path,Path,LinkOption[],OpenOption[],FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "directoryContentEquals", "(Path,Path,int,LinkOption[],FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "fileContentEquals", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "fileContentEquals", "(Path,Path,LinkOption[],OpenOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "filter", "(PathFilter,Path[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getAclEntryList", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getAclFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getDosFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getPosixFileAttributeView", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "getTempDirectory", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isDirectory", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmpty", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmptyDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isEmptyFile", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,ChronoZonedDateTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,FileTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,Instant,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isNewer", "(Path,long,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,FileTime,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,Instant,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isOlder", "(Path,long,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isPosix", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "isRegularFile", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "newDirectoryStream", "(Path,PathFilter)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "newOutputStream", "(Path,boolean)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "noFollowLinkOptionArray", "()", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readAttributes", "(Path,Class,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributes", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readBasicFileAttributesUnchecked", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readDosFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readOsFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readPosixFileAttributes", "(Path,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "readString", "(Path,Charset)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "setLastModifiedTime", "(Path,Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOf", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfDirectory", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "sizeOfDirectoryAsBigInteger", "(Path)", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "waitFor", "(Path,Duration,LinkOption[])", "generated"] + - ["org.apache.commons.io.file", "PathUtils", "walk", "(Path,PathFilter,int,boolean,FileVisitOption[])", "generated"] + - ["org.apache.commons.io.file", "StandardDeleteOption", "overrideReadOnly", "(DeleteOption[])", "generated"] + - ["org.apache.commons.io.filefilter", "AbstractFileFilter", "AbstractFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "AbstractFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(Date)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(Date,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(File)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "AgeFileFilter", "AgeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "AndFileFilter", "AndFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "addFileFilter", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "getFileFilters", "()", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "removeFileFilter", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "ConditionalFileFilter", "setFileFilters", "(List)", "generated"] + - ["org.apache.commons.io.filefilter", "FalseFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "FileFilterUtils", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(Date)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(Date,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(File)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "ageFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "directoryFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "falseFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "fileFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filter", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filter", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterList", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterList", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterSet", "(IOFileFilter,File[])", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "filterSet", "(IOFileFilter,Iterable)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "sizeRangeFileFilter", "(long,long)", "generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", "trueFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "and", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "negate", "()", "generated"] + - ["org.apache.commons.io.filefilter", "IOFileFilter", "or", "(IOFileFilter)", "generated"] + - ["org.apache.commons.io.filefilter", "OrFileFilter", "OrFileFilter", "()", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String)", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String,IOCase)", "generated"] + - ["org.apache.commons.io.filefilter", "RegexFileFilter", "RegexFileFilter", "(String,int)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "SizeFileFilter", "(long)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "SizeFileFilter", "(long,boolean)", "generated"] + - ["org.apache.commons.io.filefilter", "SizeFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.filefilter", "SymbolicLinkFileFilter", "SymbolicLinkFileFilter", "(FileVisitResult,FileVisitResult)", "generated"] + - ["org.apache.commons.io.filefilter", "TrueFileFilter", "toString", "()", "generated"] + - ["org.apache.commons.io.function", "IOBiConsumer", "accept", "(Object,Object)", "generated"] + - ["org.apache.commons.io.function", "IOBiConsumer", "andThen", "(IOBiConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOBiFunction", "apply", "(Object,Object)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "accept", "(Object)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "andThen", "(IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "forEach", "(Object[],IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "forEachIndexed", "(Stream,IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOConsumer", "noop", "()", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(Consumer)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(IOConsumer)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "apply", "(Object)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(IOSupplier)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "compose", "(Supplier)", "generated"] + - ["org.apache.commons.io.function", "IOFunction", "identity", "()", "generated"] + - ["org.apache.commons.io.function", "IORunnable", "run", "()", "generated"] + - ["org.apache.commons.io.function", "IOSupplier", "get", "()", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "andThen", "(Function)", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "andThen", "(IOFunction)", "generated"] + - ["org.apache.commons.io.function", "IOTriFunction", "apply", "(Object,Object,Object)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "CircularByteBuffer", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "CircularByteBuffer", "(int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "add", "(byte)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "add", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "clear", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "getCurrentNumberOfBytes", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "getSpace", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasBytes", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasSpace", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "hasSpace", "(int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "peek", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "read", "()", "generated"] + - ["org.apache.commons.io.input.buffer", "CircularByteBuffer", "read", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", "peek", "(byte[])", "generated"] + - ["org.apache.commons.io.input.buffer", "PeekableInputStream", "peek", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input", "AutoCloseInputStream", "AutoCloseInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "BOMInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "BOMInputStream", "(InputStream,boolean)", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "hasBOM", "()", "generated"] + - ["org.apache.commons.io.input", "BOMInputStream", "hasBOM", "(ByteOrderMark)", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "isPropagateClose", "()", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "setPropagateClose", "(boolean)", "generated"] + - ["org.apache.commons.io.input", "BoundedInputStream", "toString", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", "BrokenInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenInputStream", "BrokenInputStream", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", "BrokenReader", "()", "generated"] + - ["org.apache.commons.io.input", "BrokenReader", "BrokenReader", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(File)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(File,int)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(Path)", "generated"] + - ["org.apache.commons.io.input", "BufferedFileChannelInputStream", "BufferedFileChannelInputStream", "(Path,int)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,Charset)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,Charset,int)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,String)", "generated"] + - ["org.apache.commons.io.input", "CharSequenceInputStream", "CharSequenceInputStream", "(CharSequence,String,int)", "generated"] + - ["org.apache.commons.io.input", "CharacterFilterReader", "CharacterFilterReader", "(Reader,int)", "generated"] + - ["org.apache.commons.io.input", "CharacterSetFilterReader", "CharacterSetFilterReader", "(Reader,Integer[])", "generated"] + - ["org.apache.commons.io.input", "CharacterSetFilterReader", "CharacterSetFilterReader", "(Reader,Set)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldInputStream", "CloseShieldInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldReader", "CloseShieldReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "CloseShieldReader", "wrap", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "ClosedInputStream", "ClosedInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "ClosedReader", "ClosedReader", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "CountingInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "getCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "resetByteCount", "()", "generated"] + - ["org.apache.commons.io.input", "CountingInputStream", "resetCount", "()", "generated"] + - ["org.apache.commons.io.input", "DemuxInputStream", "DemuxInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "DemuxInputStream", "bindStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MarkShieldInputStream", "MarkShieldInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MemoryMappedFileInputStream", "MemoryMappedFileInputStream", "(Path)", "generated"] + - ["org.apache.commons.io.input", "MemoryMappedFileInputStream", "MemoryMappedFileInputStream", "(Path,int)", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", "MessageDigestCalculatingInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "MessageDigestCalculatingInputStream", "MessageDigestCalculatingInputStream", "(InputStream,String)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "(long)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "NullInputStream", "(long,boolean,boolean)", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "getPosition", "()", "generated"] + - ["org.apache.commons.io.input", "NullInputStream", "getSize", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "(long)", "generated"] + - ["org.apache.commons.io.input", "NullReader", "NullReader", "(long,boolean,boolean)", "generated"] + - ["org.apache.commons.io.input", "NullReader", "getPosition", "()", "generated"] + - ["org.apache.commons.io.input", "NullReader", "getSize", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "Observer", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "closed", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "data", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "data", "(int)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "error", "(IOException)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream$Observer", "finished", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "ObservableInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "consume", "()", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "remove", "(Observer)", "generated"] + - ["org.apache.commons.io.input", "ObservableInputStream", "removeAllObservers", "()", "generated"] + - ["org.apache.commons.io.input", "ProxyInputStream", "ProxyInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "ProxyReader", "ProxyReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "QueueInputStream", "()", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "QueueInputStream", "(BlockingQueue)", "generated"] + - ["org.apache.commons.io.input", "QueueInputStream", "newQueueOutputStream", "()", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", "availableLong", "()", "generated"] + - ["org.apache.commons.io.input", "RandomAccessFileInputStream", "isCloseOnClose", "()", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,int,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(File,int,String)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,int,Charset)", "generated"] + - ["org.apache.commons.io.input", "ReversedLinesFileReader", "ReversedLinesFileReader", "(Path,int,String)", "generated"] + - ["org.apache.commons.io.input", "SwappedDataInputStream", "SwappedDataInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "TaggedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "isCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedInputStream", "throwIfCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "TaggedReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "isCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "TaggedReader", "throwIfCauseOf", "(Throwable)", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "getPointer", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "read", "(byte[])", "generated"] + - ["org.apache.commons.io.input", "Tailer$RandomAccessResourceBridge", "seek", "(long)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "getRandomAccess", "(String)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "isNewer", "(FileTime)", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "lastModifiedFileTime", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", "size", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer", "getDelay", "()", "generated"] + - ["org.apache.commons.io.input", "Tailer", "stop", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "fileNotFound", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "fileRotated", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "handle", "(Exception)", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "handle", "(String)", "generated"] + - ["org.apache.commons.io.input", "TailerListener", "init", "(Tailer)", "generated"] + - ["org.apache.commons.io.input", "TailerListenerAdapter", "TailerListenerAdapter", "()", "generated"] + - ["org.apache.commons.io.input", "TailerListenerAdapter", "endOfFileReached", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "TimestampedObserver", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "getOpenToCloseDuration", "()", "generated"] + - ["org.apache.commons.io.input", "TimestampedObserver", "getOpenToNowDuration", "()", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterInputStream", "UncheckedFilterInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterReader", "UncheckedFilterReader", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "UncheckedFilterReader", "on", "(Reader)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(File)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(Path)", "generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", "XmlStreamReader", "(URL)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryChange", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryCreate", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onDirectoryDelete", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileChange", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileCreate", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onFileDelete", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onStart", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListener", "onStop", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationListenerAdaptor", "FileAlterationListenerAdaptor", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "FileAlterationMonitor", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "FileAlterationMonitor", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "getInterval", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "removeObserver", "(FileAlterationObserver)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "start", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "stop", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationMonitor", "stop", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "checkAndNotify", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "destroy", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "initialize", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileAlterationObserver", "removeListener", "(FileAlterationListener)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLastModified", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLength", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "getLevel", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "isDirectory", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "isExists", "()", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "refresh", "(File)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setDirectory", "(boolean)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setExists", "(boolean)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setLastModified", "(long)", "generated"] + - ["org.apache.commons.io.monitor", "FileEntry", "setLength", "(long)", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "AbstractByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "reset", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "size", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "toByteArray", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "toInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "write", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "AbstractByteArrayOutputStream", "writeTo", "(OutputStream)", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", "BrokenOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "BrokenOutputStream", "BrokenOutputStream", "(IOException)", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", "BrokenWriter", "()", "generated"] + - ["org.apache.commons.io.output", "BrokenWriter", "BrokenWriter", "(IOException)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "ByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "ByteArrayOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "ByteArrayOutputStream", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io.output", "ChunkedWriter", "ChunkedWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "ChunkedWriter", "ChunkedWriter", "(Writer,int)", "generated"] + - ["org.apache.commons.io.output", "CloseShieldWriter", "CloseShieldWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "CloseShieldWriter", "wrap", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "ClosedOutputStream", "ClosedOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "ClosedWriter", "ClosedWriter", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "getCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "resetByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "CountingOutputStream", "resetCount", "()", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", "isInMemory", "()", "generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", "toInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "DemuxOutputStream", "DemuxOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "DemuxOutputStream", "bindStream", "(OutputStream)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,Charset)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,Charset,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,CharsetEncoder)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,String)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(File,String,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,Charset)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,Charset,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,CharsetEncoder)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,String)", "generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", "FileWriterWithEncoding", "(String,String,boolean)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,Charset)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,String)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(File,boolean)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(String)", "generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", "LockableFileWriter", "(String,boolean)", "generated"] + - ["org.apache.commons.io.output", "NullOutputStream", "NullOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "NullPrintStream", "NullPrintStream", "()", "generated"] + - ["org.apache.commons.io.output", "NullWriter", "NullWriter", "()", "generated"] + - ["org.apache.commons.io.output", "ProxyWriter", "ProxyWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "QueueOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "QueueOutputStream", "(BlockingQueue)", "generated"] + - ["org.apache.commons.io.output", "QueueOutputStream", "newQueueInputStream", "()", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", "StringBuilderWriter", "()", "generated"] + - ["org.apache.commons.io.output", "StringBuilderWriter", "StringBuilderWriter", "(int)", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", "isCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedOutputStream", "throwIfCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "TaggedWriter", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "isCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "TaggedWriter", "throwIfCauseOf", "(Exception)", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "ThresholdingOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "getByteCount", "()", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "getThreshold", "()", "generated"] + - ["org.apache.commons.io.output", "ThresholdingOutputStream", "isThresholdExceeded", "()", "generated"] + - ["org.apache.commons.io.output", "UncheckedFilterWriter", "on", "(Writer)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "UnsynchronizedByteArrayOutputStream", "()", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "UnsynchronizedByteArrayOutputStream", "(int)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io.output", "UnsynchronizedByteArrayOutputStream", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", "XmlStreamWriter", "(File)", "generated"] + - ["org.apache.commons.io.serialization", "ClassNameMatcher", "matches", "(String)", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "get", "(int)", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "getBytes", "()", "generated"] + - ["org.apache.commons.io", "ByteOrderMark", "length", "()", "generated"] + - ["org.apache.commons.io", "ByteOrderParser", "parseByteOrder", "(String)", "generated"] + - ["org.apache.commons.io", "Charsets", "Charsets", "()", "generated"] + - ["org.apache.commons.io", "Charsets", "requiredCharsets", "()", "generated"] + - ["org.apache.commons.io", "Charsets", "toCharset", "(Charset)", "generated"] + - ["org.apache.commons.io", "Charsets", "toCharset", "(String)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "CopyUtils", "()", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(Reader,OutputStream)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(Reader,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(String,OutputStream)", "generated"] + - ["org.apache.commons.io", "CopyUtils", "copy", "(String,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "DirectoryWalker$CancelException", "getDepth", "()", "generated"] + - ["org.apache.commons.io", "EndianUtils", "EndianUtils", "()", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedDouble", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedDouble", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedFloat", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedFloat", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedInteger", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedInteger", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedLong", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedLong", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedShort", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedShort", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedInteger", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedInteger", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedShort", "(InputStream)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "readSwappedUnsignedShort", "(byte[],int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapDouble", "(double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapFloat", "(float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapInteger", "(int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapLong", "(long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "swapShort", "(short)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedDouble", "(OutputStream,double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedDouble", "(byte[],int,double)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedFloat", "(OutputStream,float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedFloat", "(byte[],int,float)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedInteger", "(OutputStream,int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedInteger", "(byte[],int,int)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedLong", "(OutputStream,long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedLong", "(byte[],int,long)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedShort", "(OutputStream,short)", "generated"] + - ["org.apache.commons.io", "EndianUtils", "writeSwappedShort", "(byte[],int,short)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "FileCleaner", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "exitWhenFinished", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "getInstance", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "getTrackCount", "()", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(File,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(File,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(String,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaner", "track", "(String,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "FileCleaningTracker", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "exitWhenFinished", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "getTrackCount", "()", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(File,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(File,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(String,Object)", "generated"] + - ["org.apache.commons.io", "FileCleaningTracker", "track", "(String,Object,FileDeleteStrategy)", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", "delete", "(File)", "generated"] + - ["org.apache.commons.io", "FileDeleteStrategy", "deleteQuietly", "(File)", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "()", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "(File)", "generated"] + - ["org.apache.commons.io", "FileExistsException", "FileExistsException", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystem", "getCurrent", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getIllegalFileNameChars", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getMaxFileNameLength", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getMaxPathLength", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getNameSeparator", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "getReservedFileNames", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isCasePreserving", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isCaseSensitive", "()", "generated"] + - ["org.apache.commons.io", "FileSystem", "isLegalFileName", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "FileSystem", "isReservedFileName", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "FileSystem", "supportsDriveLetter", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "FileSystemUtils", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpace", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "()", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(String)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(String,long)", "generated"] + - ["org.apache.commons.io", "FileSystemUtils", "freeSpaceKb", "(long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "FileUtils", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(BigInteger)", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(Number)", "generated"] + - ["org.apache.commons.io", "FileUtils", "byteCountToDisplaySize", "(long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "checksumCRC32", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "cleanDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "contentEquals", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "contentEqualsIgnoreEOL", "(File,File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyDirectoryToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,File,boolean,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFile", "(File,OutputStream)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFileToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyFileToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyInputStreamToFile", "(InputStream,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToDirectory", "(Iterable,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyToFile", "(InputStream,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyURLToFile", "(URL,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "copyURLToFile", "(URL,File,int,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "createParentDirectories", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "current", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "deleteDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "deleteQuietly", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "directoryContains", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceDelete", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceDeleteOnExit", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceMkdir", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "forceMkdirParent", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "getTempDirectory", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getTempDirectoryPath", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getUserDirectory", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "getUserDirectoryPath", "()", "generated"] + - ["org.apache.commons.io", "FileUtils", "isDirectory", "(File,LinkOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "isEmptyDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDate)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDate,LocalTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoLocalDateTime,ZoneId)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,ChronoZonedDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,Date)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,FileTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,Instant)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileNewer", "(File,long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDate)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDate,LocalTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoLocalDateTime,ZoneId)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,ChronoZonedDateTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,Date)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,FileTime)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,Instant)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isFileOlder", "(File,long)", "generated"] + - ["org.apache.commons.io", "FileUtils", "isRegularFile", "(File,LinkOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "isSymlink", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFiles", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFiles", "(File,String[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "iterateFilesAndDirs", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModified", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModifiedFileTime", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lastModifiedUnchecked", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lineIterator", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "lineIterator", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFiles", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFiles", "(File,String[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "listFilesAndDirs", "(File,IOFileFilter,IOFileFilter)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveDirectory", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveDirectoryToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFile", "(File,File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFile", "(File,File,CopyOption[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveFileToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "moveToDirectory", "(File,File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "newOutputStream", "(File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openInputStream", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openOutputStream", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "openOutputStream", "(File,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToByteArray", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readFileToString", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "readLines", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOf", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfAsBigInteger", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfDirectory", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "sizeOfDirectoryAsBigInteger", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "streamFiles", "(File,boolean,String[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "toFile", "(URL)", "generated"] + - ["org.apache.commons.io", "FileUtils", "toFiles", "(URL[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "touch", "(File)", "generated"] + - ["org.apache.commons.io", "FileUtils", "waitFor", "(File,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,Charset,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "write", "(File,CharSequence,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[])", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],int,int)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,Collection,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeLines", "(File,String,Collection,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,Charset)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,Charset,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,String)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,String,boolean)", "generated"] + - ["org.apache.commons.io", "FileUtils", "writeStringToFile", "(File,String,boolean)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "FilenameUtils", "()", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "directoryContains", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equals", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equals", "(String,String,boolean,IOCase)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsNormalized", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsNormalizedOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "equalsOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "getPrefixLength", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "indexOfExtension", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "indexOfLastSeparator", "(String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,Collection)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "isExtension", "(String,String[])", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatch", "(String,String)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatch", "(String,String,IOCase)", "generated"] + - ["org.apache.commons.io", "FilenameUtils", "wildcardMatchOnSystem", "(String,String)", "generated"] + - ["org.apache.commons.io", "HexDump", "HexDump", "()", "generated"] + - ["org.apache.commons.io", "HexDump", "dump", "(byte[],long,OutputStream,int)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkCompareTo", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkEndsWith", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkEquals", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkIndexOf", "(String,int,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkRegionMatches", "(String,int,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "checkStartsWith", "(String,String)", "generated"] + - ["org.apache.commons.io", "IOCase", "forName", "(String)", "generated"] + - ["org.apache.commons.io", "IOCase", "getName", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "isCaseSensitive", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "isCaseSensitive", "(IOCase)", "generated"] + - ["org.apache.commons.io", "IOCase", "toString", "()", "generated"] + - ["org.apache.commons.io", "IOCase", "value", "(IOCase,IOCase)", "generated"] + - ["org.apache.commons.io", "IOExceptionList", "checkEmpty", "(List,Object)", "generated"] + - ["org.apache.commons.io", "IOExceptionList", "getCause", "(int,Class)", "generated"] + - ["org.apache.commons.io", "IOExceptionWithCause", "IOExceptionWithCause", "(String,Throwable)", "generated"] + - ["org.apache.commons.io", "IOExceptionWithCause", "IOExceptionWithCause", "(Throwable)", "generated"] + - ["org.apache.commons.io", "IOIndexedException", "IOIndexedException", "(int,Throwable)", "generated"] + - ["org.apache.commons.io", "IOIndexedException", "getIndex", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "IOUtils", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "byteArray", "()", "generated"] + - ["org.apache.commons.io", "IOUtils", "byteArray", "(int)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable,IOConsumer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(Closeable[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "close", "(URLConnection)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable,Consumer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Closeable[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Selector)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(ServerSocket)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Socket)", "generated"] + - ["org.apache.commons.io", "IOUtils", "closeQuietly", "(Writer)", "generated"] + - ["org.apache.commons.io", "IOUtils", "consume", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEquals", "(InputStream,InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEquals", "(Reader,Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "contentEqualsIgnoreEOL", "(Reader,Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(ByteArrayOutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(Reader,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(URL,File)", "generated"] + - ["org.apache.commons.io", "IOUtils", "copy", "(URL,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(CharSequence)", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(Object[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(byte[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "length", "(char[])", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToByteArray", "(String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToByteArray", "(String,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToString", "(String,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToString", "(String,Charset,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToURL", "(String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "resourceToURL", "(String,ClassLoader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(InputStream,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(ReadableByteChannel,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skip", "(Reader,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(InputStream,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(ReadableByteChannel,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "skipFully", "(Reader,long)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toBufferedInputStream", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toBufferedInputStream", "(InputStream,int)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(InputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(Reader,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URI)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URL)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toByteArray", "(URLConnection)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URI,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "toString", "(URL,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(CharSequence,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(String,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(StringBuffer,OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(StringBuffer,OutputStream,String)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream,Charset)", "generated"] + - ["org.apache.commons.io", "IOUtils", "write", "(char[],OutputStream,String)", "generated"] + - ["org.apache.commons.io", "LineIterator", "closeQuietly", "(LineIterator)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(File)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(Path)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "create", "(String)", "generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", "toString", "()", "generated"] + - ["org.apache.commons.io", "StandardLineSeparator", "getBytes", "(Charset)", "generated"] + - ["org.apache.commons.io", "StandardLineSeparator", "getString", "()", "generated"] + - ["org.apache.commons.io", "TaggedIOException", "isTaggedWith", "(Throwable,Object)", "generated"] + - ["org.apache.commons.io", "TaggedIOException", "throwCauseIfTaggedWith", "(Throwable,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "UncheckedIO", "()", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "accept", "(IOConsumer,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "apply", "(IOBiFunction,Object,Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "get", "(IOSupplier)", "generated"] + - ["org.apache.commons.io", "UncheckedIO", "run", "(IORunnable)", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "UncheckedIOExceptions", "()", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "create", "(Object)", "generated"] + - ["org.apache.commons.io", "UncheckedIOExceptions", "wrap", "(IOException,Object)", "generated"] + + \ No newline at end of file diff --git a/java/ql/lib/ext/groovy.lang.model.yml b/java/ql/lib/ext/groovy.lang.model.yml new file mode 100644 index 00000000000..1c775bdd2e5 --- /dev/null +++ b/java/ql/lib/ext/groovy.lang.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource,boolean)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(InputStream,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(URI)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String,String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(URI)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,String[])", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,List)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,String[])", "", "Argument[0]", "groovy", "manual"] diff --git a/java/ql/lib/ext/groovy.util.model.yml b/java/ql/lib/ext/groovy.util.model.yml new file mode 100644 index 00000000000..61d1dbb6a05 --- /dev/null +++ b/java/ql/lib/ext/groovy.util.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["groovy.util", "Eval", False, "me", "(String)", "", "Argument[0]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "me", "(String,Object,String)", "", "Argument[2]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "x", "(Object,String)", "", "Argument[1]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "xy", "(Object,Object,String)", "", "Argument[2]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "xyz", "(Object,Object,Object,String)", "", "Argument[3]", "groovy", "manual"] diff --git a/java/ql/lib/ext/jakarta.faces.context.model.yml b/java/ql/lib/ext/jakarta.faces.context.model.yml new file mode 100644 index 00000000000..84a0fd22710 --- /dev/null +++ b/java/ql/lib/ext/jakarta.faces.context.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["jakarta.faces.context", "ExternalContext", True, "getRequestCookieMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestHeaderMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestHeaderValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestParameterValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.faces.context", "ExternalContext", True, "getRequestPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["jakarta.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["jakarta.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] diff --git a/java/ql/lib/ext/jakarta.json.model.yml b/java/ql/lib/ext/jakarta.json.model.yml new file mode 100644 index 00000000000..3d4d35ca4f0 --- /dev/null +++ b/java/ql/lib/ext/jakarta.json.model.yml @@ -0,0 +1,127 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["jakarta.json", "Json", False, "createArrayBuilder", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createArrayBuilder", "(JsonArray)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createMergeDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createMergePatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(JsonObject)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPatchBuilder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "createWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "decodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "Json", False, "encodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArray", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArray", False, "getValuesAs", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(BigDecimal)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(BigInteger)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonArrayBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonObjectBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(JsonValue)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,BigDecimal)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,BigInteger)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonArrayBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonObjectBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,JsonValue)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "add", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonArrayBuilder", False, "setNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonMergePatch", False, "toJsonValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigDecimalValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigIntegerValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "bigIntegerValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "doubleValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "intValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "intValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "longValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "longValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonNumber", False, "numberValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObject", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "add", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonObjectBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatch", False, "toJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "move", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "move", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "test", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.json", "JsonPatchBuilder", False, "test", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "add", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "getValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "read", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReader", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonReaderFactory", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonString", False, "getChars", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonString", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonStructure", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "asJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "asJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonValue", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "writeArray", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriter", False, "writeObject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.json", "JsonWriterFactory", False, "createWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/jakarta.json.stream.model.yml b/java/ql/lib/ext/jakarta.json.stream.model.yml new file mode 100644 index 00000000000..cc6386121d5 --- /dev/null +++ b/java/ql/lib/ext/jakarta.json.stream.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["jakarta.json.stream", "JsonParserFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.client.model.yml b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml new file mode 100644 index 00000000000..821ea0ad640 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["jakarta.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.container.model.yml b/java/ql/lib/ext/jakarta.ws.rs.container.model.yml new file mode 100644 index 00000000000..05ccfd62000 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.container.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getAcceptableLanguages", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getAcceptableMediaTypes", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getEntityStream", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getHeaderString", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getLanguage", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getMediaType", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.ws.rs.container", "ContainerRequestContext", True, "getUriInfo", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml new file mode 100644 index 00000000000..593128bd953 --- /dev/null +++ b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml @@ -0,0 +1,167 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["jakarta.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] + - ["jakarta.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["jakarta.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Cookie", False, "Cookie", "", "", "Argument[0..4]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getDomain", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "getVersion", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Cookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "asMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "param", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # Methods that Date have to be syntax-checked, but those returning MediaType + # or Locale are assumed potentially dangerous, as these types do not generally check that the + # input data is recognised, only that it conforms to the expected syntax. + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getHeaderString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getLanguage", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getMediaType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getRequestHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "HttpHeaders", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", False, "MediaType", "", "", "Argument[0..2]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getSubtype", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "getType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MediaType", True, "withCharset", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["jakarta.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", False, "NewCookie", "", "", "Argument[0..9]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getComment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getExpiry", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "getMaxAge", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", True, "toCookie", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # The returned ResponseBuilder gains taint from a tainted entity or existing Response + - ["jakarta.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # Becomes tainted by a tainted entity, but not by metadata, headers etc + # Build() method returns taint + # Almost all methods are fluent, and so preserve value + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "contentLocation", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "cookie", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "encoding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "expires", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "header", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "language", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "link", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "links", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "location", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "status", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "tag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "type", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "variant", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "Response$ResponseBuilder", True, "variants", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromLink", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "toTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jakarta.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getAbsolutePathBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPathParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getRequestUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "getRequestUriBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "relativize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["jakarta.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.beans.model.yml b/java/ql/lib/ext/java.beans.model.yml new file mode 100644 index 00000000000..0d24c372fb0 --- /dev/null +++ b/java/ql/lib/ext/java.beans.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.beans", "XMLDecoder", False, "XMLDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml new file mode 100644 index 00000000000..87d6c6311e7 --- /dev/null +++ b/java/ql/lib/ext/java.io.model.yml @@ -0,0 +1,86 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "print", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "writeUTF", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "Writer", True, "append", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "write-file", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.io", "BufferedInputStream", False, "BufferedInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "BufferedReader", False, "BufferedReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "BufferedReader", True, "readLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayInputStream", False, "ByteArrayInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "ByteArrayOutputStream", False, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "CharArrayReader", False, "CharArrayReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "CharArrayWriter", True, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInput", True, "readFully", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "DataInput", True, "readLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "toURI", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "read", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "readAllBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "InputStream", True, "readNBytes", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStream", True, "readNBytes", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "InputStream", True, "transferTo", "(OutputStream)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "InputStreamReader", False, "InputStreamReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "ObjectInput", True, "read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "ObjectInputStream", False, "ObjectInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "Reader", True, "read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["java.io", "Reader", True, "read", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.io", "Writer", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml new file mode 100644 index 00000000000..5ec7a1bba7a --- /dev/null +++ b/java/ql/lib/ext/java.lang.model.yml @@ -0,0 +1,88 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"] + - ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "split", "(String)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "String", False, "split", "(String,int)", "", "Argument[0]", "regex-use[-1]", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier,Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.lang", "AbstractStringBuilder", True, "AbstractStringBuilder", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "getChars", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "replace", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Appendable", True, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "Appendable", True, "append", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "CharSequence", True, "charAt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "CharSequence", True, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "CharSequence", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Iterable", True, "forEach", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.lang", "Iterable", True, "iterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Iterable", True, "spliterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.lang", "Object", True, "clone", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.lang", "String", False, "String", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "copyValueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "endsWith", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(Locale,String,Object[])", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(Locale,String,Object[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "formatted", "(Object[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "formatted", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "getBytes", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["java.lang", "String", False, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "getChars", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["java.lang", "String", False, "indent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "intern", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "join", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "repeat", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replace", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replaceAll", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "replaceFirst", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "split", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "strip", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripIndent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripLeading", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "stripTrailing", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toLowerCase", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "toString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.lang", "String", False, "toUpperCase", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "translateEscapes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "valueOf", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "StringBuffer", True, "StringBuffer", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.net.http.model.yml b/java/ql/lib/ext/java.net.http.model.yml new file mode 100644 index 00000000000..d967f46494b --- /dev/null +++ b/java/ql/lib/ext/java.net.http.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["java.net.http", "WebSocket$Listener", True, "onText", "(WebSocket,CharSequence,boolean)", "", "Parameter[1]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.net.http", "HttpRequest", False, "newBuilder", "", "", "Argument[0]", "open-url", "manual"] + - ["java.net.http", "HttpRequest$Builder", False, "uri", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/java.net.model.yml b/java/ql/lib/ext/java.net.model.yml new file mode 100644 index 00000000000..2c153b37a05 --- /dev/null +++ b/java/ql/lib/ext/java.net.model.yml @@ -0,0 +1,30 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["java.net", "URLConnection", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.net", "URL", False, "openConnection", "", "", "Argument[-1]", "open-url", "manual"] + - ["java.net", "URL", False, "openStream", "", "", "Argument[-1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "URLClassLoader", False, "newInstance", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.net", "URI", False, "URI", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.net", "URI", False, "create", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toAsciiString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "toURL", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.net", "URL", False, "URL", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.net", "URLDecoder", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.channels.model.yml b/java/ql/lib/ext/java.nio.channels.model.yml new file mode 100644 index 00000000000..e6b3e301bdf --- /dev/null +++ b/java/ql/lib/ext/java.nio.channels.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.nio.channels", "Channels", False, "newChannel", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.channels", "ReadableByteChannel", True, "read", "(ByteBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml new file mode 100644 index 00000000000..129bf048b96 --- /dev/null +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -0,0 +1,35 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.nio.file", "Files", False, "copy", "", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createLink", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createSymbolicLink", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createTempDirectory", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "createTempFile", "(Path,String,String,FileAttribute[])", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "write-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[1]", "write-file", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.nio.file", "FileSystem", True, "getPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "resolve", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", False, "toFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "toUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Paths", True, "get", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml new file mode 100644 index 00000000000..ad03fbe2371 --- /dev/null +++ b/java/ql/lib/ext/java.nio.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml new file mode 100644 index 00000000000..e7017ebd40a --- /dev/null +++ b/java/ql/lib/ext/java.sql.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "Statement", True, "addBatch", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "execute", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeQuery", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "executeUpdate", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml new file mode 100644 index 00000000000..9c202220dde --- /dev/null +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util.concurrent", "BlockingDeque", True, "offerFirst", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "offerLast", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "pollFirst", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "pollLast", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "putFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "putLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "takeFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingDeque", True, "takeLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "drainTo", "(Collection)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "drainTo", "(Collection,int)", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "offer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.function.model.yml b/java/ql/lib/ext/java.util.function.model.yml new file mode 100644 index 00000000000..9a608462a92 --- /dev/null +++ b/java/ql/lib/ext/java.util.function.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.util.function", "Predicate", False, "test", "(Object)", "", "Argument[-1]", "regex-use[0]", "manual"] diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml new file mode 100644 index 00000000000..4f96b8f28ee --- /dev/null +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -0,0 +1,44 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.util.logging", "Logger", True, "config", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String)", "", "Argument[0..1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object[])", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String)", "", "Argument[0..1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "fine", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "finer", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "finest", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Throwable,Supplier)", "", "Argument[2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "log", "(LogRecord)", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object[])", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Throwable)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Supplier)", "", "Argument[1..3]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[4..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object[])", "", "Argument[1..5]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Throwable)", "", "Argument[1..4]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "severe", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "warning", "", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml new file mode 100644 index 00000000000..38368d87bf4 --- /dev/null +++ b/java/ql/lib/ext/java.util.model.yml @@ -0,0 +1,357 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleEntry", False, "SimpleEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "AbstractMap$SimpleImmutableEntry", False, "SimpleImmutableEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "ArrayDeque", False, "ArrayDeque", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "ArrayList", False, "ArrayList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Arrays", False, "asList", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Arrays", False, "copyOf", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "copyOfRange", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(Object[],Object)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(Object[],int,int,Object)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(boolean[],boolean)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(boolean[],int,int,boolean)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(byte[],byte)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(byte[],int,int,byte)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(char[],char)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(char[],int,int,char)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(double[],double)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(double[],int,int,double)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(float[],float)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(float[],int,int,float)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(int[],int)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(int[],int,int,int)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(long[],int,int,long)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(long[],long)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(short[],int,int,short)", "", "Argument[3]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "fill", "(short[],short)", "", "Argument[1]", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Arrays", False, "spliterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Arrays", False, "stream", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "decode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Decoder", False, "wrap", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encode", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "encodeToString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Base64$Encoder", False, "wrap", "(OutputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util", "Collection", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Collection", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Collection", True, "parallelStream", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collection", True, "stream", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collection", True, "toArray", "", "", "Argument[-1].Element", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Collection", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util", "Collections", False, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedCollection", "(Collection,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedList", "(List,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedMap", "(Map,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedMap", "(Map,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableMap", "(NavigableMap,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableMap", "(NavigableMap,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedNavigableSet", "(NavigableSet,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedSet", "(Set,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedMap", "(SortedMap,Class,Class)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedMap", "(SortedMap,Class,Class)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "checkedSortedSet", "(SortedSet,Class)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "copy", "(List,List)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "enumeration", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "fill", "(List,Object)", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "list", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "max", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Collections", False, "min", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Collections", False, "nCopies", "(int,Object)", "", "Argument[1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "replaceAll", "(List,Object,Object)", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["java.util", "Collections", False, "singleton", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "singletonList", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "singletonMap", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "singletonMap", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedCollection", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedList", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "synchronizedSortedSet", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableCollection", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableList", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableMap", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableMap", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableMap", "(NavigableMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableNavigableSet", "(NavigableSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedMap", "(SortedMap)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Collections", False, "unmodifiableSortedSet", "(SortedSet)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Deque", True, "addFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "addLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "descendingIterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Deque", True, "getFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "getLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "offerFirst", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "offerLast", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "peekFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "peekLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pollFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pollLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "pop", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "push", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Deque", True, "removeFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Deque", True, "removeLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "elements", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Dictionary", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "keys", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Dictionary", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Dictionary", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(EnumMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(EnumMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Enumeration", True, "asIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Enumeration", True, "nextElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "HashSet", False, "HashSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Hashtable", False, "Hashtable", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Hashtable", False, "Hashtable", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "IdentityHashMap", False, "IdentityHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "IdentityHashMap", False, "IdentityHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Iterator", True, "forEachRemaining", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Iterator", True, "next", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "LinkedHashMap", False, "LinkedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "LinkedHashMap", False, "LinkedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "LinkedHashSet", False, "LinkedHashSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "LinkedList", False, "LinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "add", "(int,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "addAll", "(int,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", True, "get", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "listIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object)", "", "Argument[0..3]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object)", "", "Argument[0..4]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", False, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "List", True, "remove", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "List", True, "set", "(int,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "List", True, "subList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "ListIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", False, "copyOf", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "copyOf", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "entry", "(Object,Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "entry", "(Object,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["java.util", "Map", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["java.util", "Map", True, "forEach", "(BiConsumer)", "", "Argument[-1].MapKey", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Map", True, "forEach", "(BiConsumer)", "", "Argument[-1].MapValue", "Argument[0].Parameter[1]", "value", "manual"] + - ["java.util", "Map", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Map", True, "merge", "(Object,Object,BiFunction)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[10]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[11]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[12]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[13]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[14]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[15]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[16]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[17]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[18]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[19]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[2]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[3]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[4]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[5]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[6]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[7]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[8]", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "of", "", "", "Argument[9]", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", False, "ofEntries", "", "", "Argument[0].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "Map", False, "ofEntries", "", "", "Argument[0].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "put", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "putIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Map", True, "replace", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Map", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Map$Entry", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Map$Entry", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "ceilingEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "ceilingEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "descendingMap", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "descendingMap", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "firstEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "firstEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "floorEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "floorEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "headMap", "(Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "headMap", "(Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "higherEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "higherEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "lastEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "lastEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "lowerEntry", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "lowerEntry", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollFirstEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollFirstEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollLastEntry", "()", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "pollLastEntry", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "subMap", "(Object,boolean,Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "subMap", "(Object,boolean,Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableMap", True, "tailMap", "(Object,boolean)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "NavigableMap", True, "tailMap", "(Object,boolean)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "ceiling", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "descendingIterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "descendingSet", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "floor", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "headSet", "(Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "higher", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "lower", "(Object)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "pollFirst", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "pollLast", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "NavigableSet", True, "subSet", "(Object,boolean,Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "NavigableSet", True, "tailSet", "(Object,boolean)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElse", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElse", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "requireNonNullElseGet", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Objects", False, "toString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "filter", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "flatMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "flatMap", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "ifPresent", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "ifPresentOrElse", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "map", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util", "Optional", False, "map", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "of", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "ofNullable", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "or", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Optional", False, "or", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElse", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElse", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseGet", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseGet", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "orElseThrow", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Optional", False, "stream", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(PriorityQueue)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "PriorityQueue", False, "PriorityQueue", "(SortedSet)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "getProperty", "(String,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "Properties", True, "setProperty", "(String,String)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "Queue", True, "element", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "offer", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Queue", True, "peek", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "poll", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Queue", True, "remove", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "Scanner", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util", "Scanner", True, "findInLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "findWithinHorizon", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextLine", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "nextShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "Scanner", True, "reset", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "skip", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useDelimiter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useLocale", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Scanner", True, "useRadix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["java.util", "Set", False, "copyOf", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object)", "", "Argument[0..2]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object)", "", "Argument[0..3]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object)", "", "Argument[0..4]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Set", False, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedMap", True, "headMap", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "headMap", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedMap", True, "subMap", "(Object,Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "subMap", "(Object,Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedMap", True, "tailMap", "(Object)", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["java.util", "SortedMap", True, "tailMap", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["java.util", "SortedSet", True, "first", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "SortedSet", True, "headSet", "(Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedSet", True, "last", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "SortedSet", True, "subSet", "(Object,Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "SortedSet", True, "tailSet", "(Object)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Stack", True, "peek", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Stack", True, "pop", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Stack", True, "push", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "StringTokenizer", False, "StringTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util", "StringTokenizer", False, "nextElement", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "StringTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["java.util", "TreeSet", False, "TreeSet", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "TreeSet", False, "TreeSet", "(SortedSet)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", False, "Vector", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "addElement", "(Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "copyInto", "(Object[])", "", "Argument[-1].Element", "Argument[0].ArrayElement", "value", "manual"] + - ["java.util", "Vector", True, "elementAt", "(int)", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "elements", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util", "Vector", True, "firstElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "insertElementAt", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "Vector", True, "lastElement", "()", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["java.util", "Vector", True, "setElementAt", "(Object,int)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.util", "WeakHashMap", False, "WeakHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["java.util", "WeakHashMap", False, "WeakHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.regex.model.yml b/java/ql/lib/ext/java.util.regex.model.yml new file mode 100644 index 00000000000..79f50e55e9d --- /dev/null +++ b/java/ql/lib/ext/java.util.regex.model.yml @@ -0,0 +1,26 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.util.regex", "Matcher", False, "matches", "()", "", "Argument[-1]", "regex-use[f]", "manual"] + - ["java.util.regex", "Pattern", False, "asMatchPredicate", "()", "", "Argument[-1]", "regex-use[f]", "manual"] + - ["java.util.regex", "Pattern", False, "compile", "(String)", "", "Argument[0]", "regex-use[]", "manual"] + - ["java.util.regex", "Pattern", False, "compile", "(String,int)", "", "Argument[0]", "regex-use[]", "manual"] + - ["java.util.regex", "Pattern", False, "matcher", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "matches", "(String,CharSequence)", "", "Argument[0]", "regex-use[f1]", "manual"] + - ["java.util.regex", "Pattern", False, "split", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "split", "(CharSequence,int)", "", "Argument[-1]", "regex-use[0]", "manual"] + - ["java.util.regex", "Pattern", False, "splitAsStream", "(CharSequence)", "", "Argument[-1]", "regex-use[0]", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util.regex", "Matcher", False, "group", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "matcher", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "quote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "split", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml new file mode 100644 index 00000000000..4ce3812336e --- /dev/null +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -0,0 +1,89 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util.stream", "BaseStream", True, "iterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "onClose", "(Runnable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "parallel", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "sequential", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "spliterator", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "BaseStream", True, "unordered", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "anyMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[-1].Element", "Argument[1].Parameter[1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[0].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[2].Parameter[0..1]", "Argument[1].Parameter[0]", "value", "manual"] + # collect(Collector collector) is handled separately on a case-by-case basis as it is too complex for MaD + - ["java.util.stream", "Stream", True, "concat", "(Stream,Stream)", "", "Argument[0..1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "distinct", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "dropWhile", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "dropWhile", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "filter", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "filter", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "findAny", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "findFirst", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMap", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMap", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToDouble", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToInt", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "flatMapToLong", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "forEach", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "forEachOrdered", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "generate", "(Supplier)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[0]", "Argument[1..2].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[2].ReturnValue", "Argument[1..2].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,Predicate,UnaryOperator)", "", "Argument[2].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[1].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "iterate", "(Object,UnaryOperator)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "limit", "(long)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + # Missing for mapMulti(BiConsumer) (not currently supported): + # Argument[0] of Parameter[1] of Argument[0] -> Element of Parameter[1] of Argument[0] + # Element of Parameter[1] of Argument[0] -> Element of ReturnValue + - ["java.util.stream", "Stream", True, "mapMulti", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToDouble", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToInt", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapMultiToLong", "(BiConsumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToDouble", "(ToDoubleFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToInt", "(ToIntFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "mapToLong", "(ToLongFunction)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "max", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "max", "(Comparator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "min", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "min", "(Comparator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "noneMatch", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "ofNullable", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "peek", "(Consumer)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "peek", "(Consumer)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[0].ReturnValue", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(BinaryOperator)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[-1].Element", "Argument[1].Parameter[1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "Argument[2].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BiFunction,BinaryOperator)", "", "Argument[1..2].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[-1].Element", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[0]", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[1].ReturnValue", "Argument[1].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "reduce", "(Object,BinaryOperator)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + - ["java.util.stream", "Stream", True, "skip", "(long)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "sorted", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "sorted", "(Comparator)", "", "Argument[-1].Element", "Argument[0].Parameter[0..1]", "value", "manual"] + - ["java.util.stream", "Stream", True, "takeWhile", "(Predicate)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "takeWhile", "(Predicate)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "Stream", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util.stream", "Stream", True, "toList", "()", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.zip.model.yml b/java/ql/lib/ext/java.util.zip.model.yml new file mode 100644 index 00000000000..fd9c0173016 --- /dev/null +++ b/java/ql/lib/ext/java.util.zip.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.util.zip", "GZIPInputStream", False, "GZIPInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.util.zip", "ZipInputStream", False, "ZipInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.faces.context.model.yml b/java/ql/lib/ext/javax.faces.context.model.yml new file mode 100644 index 00000000000..ad33971c2c3 --- /dev/null +++ b/java/ql/lib/ext/javax.faces.context.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.faces.context", "ExternalContext", True, "getRequestCookieMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestHeaderMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestHeaderValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestParameterValuesMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.faces.context", "ExternalContext", True, "getRequestPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["javax.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] diff --git a/java/ql/lib/ext/javax.jms.model.yml b/java/ql/lib/ext/javax.jms.model.yml new file mode 100644 index 00000000000..fed2a255ebd --- /dev/null +++ b/java/ql/lib/ext/javax.jms.model.yml @@ -0,0 +1,80 @@ + # This model covers JMS API versions 1 and 2. + # + # https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html + # https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html + # +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.jms", "JMSConsumer", True, "receive", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveBody", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveBodyNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "JMSConsumer", True, "receiveNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageConsumer", True, "receive", "", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageConsumer", True, "receiveNoWait", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "MessageListener", True, "onMessage", "(Message)", "", "Parameter[0]", "remote", "manual"] + - ["javax.jms", "QueueRequestor", True, "request", "(Message)", "", "ReturnValue", "remote", "manual"] + - ["javax.jms", "TopicRequestor", True, "request", "(Message)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.jms", "BytesMessage", True, "readBoolean", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readChar", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readDouble", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readFloat", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readLong", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUTF", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUnsignedByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "BytesMessage", True, "readUnsignedShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getBoolean", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getByte", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getBytes", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getChar", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getDouble", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getFloat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getInt", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getLong", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getMapNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getObject", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getShort", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "MapMessage", True, "getString", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getBody", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getBooleanProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getByteProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getDoubleProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getFloatProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getIntProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSCorrelationID", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSCorrelationIDAsBytes", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSDestination", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSReplyTo", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getJMSType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getLongProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getObjectProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getPropertyNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getShortProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Message", True, "getStringProperty", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "ObjectMessage", True, "getObject", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Queue", True, "getQueueName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Queue", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readBoolean", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readByte", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readBytes", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readChar", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readDouble", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readFloat", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readLong", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readObject", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readShort", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "StreamMessage", True, "readString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "TextMessage", True, "getText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Topic", True, "getTopicName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.jms", "Topic", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.json.model.yml b/java/ql/lib/ext/javax.json.model.yml new file mode 100644 index 00000000000..47deffe31b9 --- /dev/null +++ b/java/ql/lib/ext/javax.json.model.yml @@ -0,0 +1,127 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.json", "Json", False, "createArrayBuilder", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createArrayBuilder", "(JsonArray)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createMergeDiff", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createMergePatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(JsonObject)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createObjectBuilder", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPatchBuilder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "createWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "decodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "Json", False, "encodePointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArray", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArray", False, "getValuesAs", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(BigDecimal)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(BigInteger)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonArrayBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonObjectBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(JsonValue)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,BigDecimal)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,BigInteger)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonArrayBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonObjectBuilder)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,JsonValue)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "add", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addAll", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonArrayBuilder", False, "setNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonMergePatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonMergePatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonMergePatch", False, "toJsonValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigDecimalValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigIntegerValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "bigIntegerValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "doubleValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "intValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "intValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "longValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "longValueExact", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonNumber", False, "numberValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObject", False, "getJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getJsonString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObject", False, "getString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "add", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addAll", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "addNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonObjectBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatch", False, "apply", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatch", False, "apply", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatch", False, "toJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "copy", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "move", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "move", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "test", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.json", "JsonPatchBuilder", False, "test", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "add", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "add", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "getValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "replace", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "read", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReader", False, "readValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonReaderFactory", False, "createReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonString", False, "getChars", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonString", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonStructure", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "asJsonArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "asJsonObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonValue", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "writeArray", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriter", False, "writeObject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.json", "JsonWriterFactory", False, "createWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.json.stream.model.yml b/java/ql/lib/ext/javax.json.stream.model.yml new file mode 100644 index 00000000000..77d564bfb69 --- /dev/null +++ b/java/ql/lib/ext/javax.json.stream.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.json.stream", "JsonParserFactory", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.management.remote.model.yml b/java/ql/lib/ext/javax.management.remote.model.yml new file mode 100644 index 00000000000..3751017d4e6 --- /dev/null +++ b/java/ql/lib/ext/javax.management.remote.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.management.remote", "JMXConnector", True, "connect", "", "", "Argument[-1]", "jndi-injection", "manual"] + - ["javax.management.remote", "JMXConnectorFactory", False, "connect", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/javax.naming.directory.model.yml b/java/ql/lib/ext/javax.naming.directory.model.yml new file mode 100644 index 00000000000..bb350a084cb --- /dev/null +++ b/java/ql/lib/ext/javax.naming.directory.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.naming.directory", "DirContext", True, "search", "", "", "Argument[0..1]", "ldap", "manual"] diff --git a/java/ql/lib/ext/javax.naming.model.yml b/java/ql/lib/ext/javax.naming.model.yml new file mode 100644 index 00000000000..c55f76557d6 --- /dev/null +++ b/java/ql/lib/ext/javax.naming.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.naming", "Context", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "lookupLink", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "Context", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["javax.naming", "InitialContext", True, "doLookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/javax.net.ssl.model.yml b/java/ql/lib/ext/javax.net.ssl.model.yml new file mode 100644 index 00000000000..7cbed92c184 --- /dev/null +++ b/java/ql/lib/ext/javax.net.ssl.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.net.ssl", "HttpsURLConnection", True, "setDefaultHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] + - ["javax.net.ssl", "HttpsURLConnection", True, "setHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] diff --git a/java/ql/lib/ext/javax.script.model.yml b/java/ql/lib/ext/javax.script.model.yml new file mode 100644 index 00000000000..1ca0311906a --- /dev/null +++ b/java/ql/lib/ext/javax.script.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.script", "CompiledScript", False, "eval", "", "", "Argument[-1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/javax.servlet.http.model.yml b/java/ql/lib/ext/javax.servlet.http.model.yml new file mode 100644 index 00000000000..9833d356835 --- /dev/null +++ b/java/ql/lib/ext/javax.servlet.http.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.servlet.http", "Cookie", False, "getComment", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "Cookie", False, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "Cookie", False, "getValue", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeader", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeaderNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getHeaders", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getQueryString", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRemoteUser", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURI", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet.http", "HttpServletRequest", False, "getRequestURL", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.servlet.http", "HttpServletResponse", False, "addCookie", "", "", "Argument[0]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "addHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "sendError", "(int,String)", "", "Argument[1]", "information-leak", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "setHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.servlet.http", "Cookie", False, "Cookie", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.servlet.http", "Cookie", False, "Cookie", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.servlet.model.yml b/java/ql/lib/ext/javax.servlet.model.yml new file mode 100644 index 00000000000..ba850941729 --- /dev/null +++ b/java/ql/lib/ext/javax.servlet.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.servlet", "ServletRequest", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["javax.servlet", "ServletRequest", False, "getReader", "()", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/javax.validation.model.yml b/java/ql/lib/ext/javax.validation.model.yml new file mode 100644 index 00000000000..2f1f3d9a75c --- /dev/null +++ b/java/ql/lib/ext/javax.validation.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.validation", "ConstraintValidator", True, "isValid", "", "", "Parameter[0]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.validation", "ConstraintValidatorContext", True, "buildConstraintViolationWithTemplate", "", "", "Argument[0]", "bean-validation", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.client.model.yml b/java/ql/lib/ext/javax.ws.rs.client.model.yml new file mode 100644 index 00000000000..0a5a01c3338 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.client.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.container.model.yml b/java/ql/lib/ext/javax.ws.rs.container.model.yml new file mode 100644 index 00000000000..a76f848a597 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.container.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getAcceptableLanguages", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getAcceptableMediaTypes", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getEntityStream", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getHeaderString", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getLanguage", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getMediaType", "", "", "ReturnValue", "remote", "manual"] + - ["javax.ws.rs.container", "ContainerRequestContext", True, "getUriInfo", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.core.model.yml b/java/ql/lib/ext/javax.ws.rs.core.model.yml new file mode 100644 index 00000000000..c7fb603d3c4 --- /dev/null +++ b/java/ql/lib/ext/javax.ws.rs.core.model.yml @@ -0,0 +1,168 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] + - ["javax.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - ["javax.ws.rs.core", "ResponseBuilder", False, "header", "", "", "Argument[1]", "header-splitting", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "AbstractMultivaluedMap", False, "AbstractMultivaluedMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["javax.ws.rs.core", "Cookie", False, "Cookie", "", "", "Argument[0..4]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getDomain", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "getVersion", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Cookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", False, "Form", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Form", True, "asMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Form", True, "param", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Form", True, "param", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "GenericEntity", False, "GenericEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "GenericEntity", True, "getEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # Methods that Date have to be syntax-checked, but those returning MediaType + # or Locale are assumed potentially dangerous, as these types do not generally check that the + # input data is recognised, only that it conforms to the expected syntax. + - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableLanguages", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getAcceptableMediaTypes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getCookies", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getHeaderString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getLanguage", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getMediaType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getRequestHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "HttpHeaders", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", False, "MediaType", "", "", "Argument[0..2]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getSubtype", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "getType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MediaType", True, "withCharset", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedHashMap", False, "MultivaluedHashMap", "(MultivaluedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addAll", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "addFirst", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["javax.ws.rs.core", "MultivaluedMap", True, "putSingle", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["javax.ws.rs.core", "NewCookie", False, "NewCookie", "", "", "Argument[0..9]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getComment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getExpiry", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "getMaxAge", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", True, "toCookie", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "NewCookie", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "PathSegment", True, "getMatrixParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "PathSegment", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # The returned ResponseBuilder gains taint from a tainted entity or existing Response + - ["javax.ws.rs.core", "Response", False, "accepted", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response", False, "fromResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response", False, "ok", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + # Becomes tainted by a tainted entity, but not by metadata, headers etc + # Build() method returns taint + # Almost all methods are fluent, and so preserve value + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "allow", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "cacheControl", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "contentLocation", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "cookie", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "encoding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "entity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "expires", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "header", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "language", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "link", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "links", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "location", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "status", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "tag", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "type", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "variant", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "Response$ResponseBuilder", True, "variants", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "build", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncoded", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromEncodedMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "buildFromMap", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "fragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromLink", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "host", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "matrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "path", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "queryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceMatrixParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplate", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplateFromEncoded", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplates", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "resolveTemplatesFromEncoded", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "scheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "schemeSpecificPart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "segment", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "toTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "uri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["javax.ws.rs.core", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getAbsolutePath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getAbsolutePathBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPathParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getRequestUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "getRequestUriBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "relativize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.ws.rs.core", "UriInfo", True, "resolve", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.model.yml b/java/ql/lib/ext/javax.xml.transform.model.yml new file mode 100644 index 00000000000..d9123a46fc7 --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.xml.transform", "Transformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.sax.model.yml b/java/ql/lib/ext/javax.xml.transform.sax.model.yml new file mode 100644 index 00000000000..90d583b5116 --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.sax.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.xml.transform.sax", "SAXSource", False, "SAXSource", "(InputSource)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "SAXSource", "(XMLReader,InputSource)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "getInputSource", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["javax.xml.transform.sax", "SAXSource", False, "sourceToInputSource", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.stream.model.yml b/java/ql/lib/ext/javax.xml.transform.stream.model.yml new file mode 100644 index 00000000000..5098f9badfc --- /dev/null +++ b/java/ql/lib/ext/javax.xml.transform.stream.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.xml.transform.stream", "StreamSource", False, "StreamSource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["javax.xml.transform.stream", "StreamSource", False, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.xml.xpath.model.yml b/java/ql/lib/ext/javax.xml.xpath.model.yml new file mode 100644 index 00000000000..68f51a34a2e --- /dev/null +++ b/java/ql/lib/ext/javax.xml.xpath.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["javax.xml.xpath", "XPath", True, "compile", "", "", "Argument[0]", "xpath", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluate", "", "", "Argument[0]", "xpath", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluateExpression", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/jodd.json.model.yml b/java/ql/lib/ext/jodd.json.model.yml new file mode 100644 index 00000000000..cf8005bf909 --- /dev/null +++ b/java/ql/lib/ext/jodd.json.model.yml @@ -0,0 +1,21 @@ + # A partial model of jodd.json.JsonParser noting fluent methods. + # + # This means that DataFlow::localFlow and similar methods are aware + # that the result of (e.g.) JsonParser.allowClass is an alias of the + # qualifier. + # +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["jodd.json", "JsonParser", False, "allowAllClasses", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "allowClass", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "lazy", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "looseMode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "map", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "setClassMetadataName", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "strictTypes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "useAltPaths", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "withClassMetadata", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["jodd.json", "JsonParser", False, "withValueConverter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/kotlin.collections.model.yml b/java/ql/lib/ext/kotlin.collections.model.yml new file mode 100644 index 00000000000..b854230b9c3 --- /dev/null +++ b/java/ql/lib/ext/kotlin.collections.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["kotlin.collections", "ArraysKt", False, "withIndex", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/kotlin.jvm.internal.model.yml b/java/ql/lib/ext/kotlin.jvm.internal.model.yml new file mode 100644 index 00000000000..413642bbeee --- /dev/null +++ b/java/ql/lib/ext/kotlin.jvm.internal.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["kotlin.jvm.internal", "ArrayIteratorKt", False, "iterator", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/net.sf.saxon.s9api.model.yml b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml new file mode 100644 index 00000000000..cbe916fd018 --- /dev/null +++ b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "applyTemplates", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callFunction", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callTemplate", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "XsltTransformer", False, "transform", "", "", "Argument[-1]", "xslt", "manual"] diff --git a/java/ql/lib/ext/ognl.enhance.model.yml b/java/ql/lib/ext/ognl.enhance.model.yml new file mode 100644 index 00000000000..6e3a27f34ae --- /dev/null +++ b/java/ql/lib/ext/ognl.enhance.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["ognl.enhance", "ExpressionAccessor", True, "get", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl.enhance", "ExpressionAccessor", True, "set", "", "", "Argument[-1]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/ognl.model.yml b/java/ql/lib/ext/ognl.model.yml new file mode 100644 index 00000000000..23de976ef98 --- /dev/null +++ b/java/ql/lib/ext/ognl.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["ognl", "Node", False, "getValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl", "Node", False, "setValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["ognl", "Ognl", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["ognl", "Ognl", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml new file mode 100644 index 00000000000..7e8459daedc --- /dev/null +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -0,0 +1,58 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["okhttp3", "Request", True, "Request", "", "", "Argument[0]", "open-url", "manual"] + - ["okhttp3", "Request$Builder", True, "url", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["okhttp3", "HttpUrl", False, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl", False, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl", False, "url", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegments", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedPathSegments", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addEncodedQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegments", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addPathSegments", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "addQueryParameter", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedFragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedFragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPassword", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedPath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "encodedUsername", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "host", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "password", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "port", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "port", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removeAllEncodedQueryParameters", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removeAllQueryParameters", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "removePathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setEncodedQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setPathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setPathSegment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["okhttp3", "HttpUrl$Builder", False, "username", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.codec.model.yml b/java/ql/lib/ext/org.apache.commons.codec.model.yml new file mode 100644 index 00000000000..78d41e6e273 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.codec.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.codec", "BinaryDecoder", True, "decode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "BinaryEncoder", True, "encode", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "Decoder", True, "decode", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "Encoder", True, "encode", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "StringDecoder", True, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.codec", "StringEncoder", True, "encode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml new file mode 100644 index 00000000000..64994a3567c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.bag.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag + - ["org.apache.commons.collections.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bag", "AbstractSortedBagDecorator", True, "AbstractSortedBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionBag", True, "CollectionBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionBag", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionSortedBag", True, "CollectionSortedBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "CollectionSortedBag", True, "collectionSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "HashBag", True, "HashBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "PredicatedBag", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "PredicatedSortedBag", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "SynchronizedBag", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "SynchronizedSortedBag", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TransformedBag", True, "transformedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TransformedSortedBag", True, "transformedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "TreeBag", True, "TreeBag", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "UnmodifiableBag", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.bag", "UnmodifiableSortedBag", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml new file mode 100644 index 00000000000..067219984bf --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.bidimap.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml new file mode 100644 index 00000000000..ce1caf3d473 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.collection.model.yml @@ -0,0 +1,46 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedCollection + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "CompositeCollection", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "addComposited", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "getCollections", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection", True, "toCollection", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "IndexedCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "nonUniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "uniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "IndexedCollection", True, "values", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "PredicatedCollection$Builder", True, "rejectedElements", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "SynchronizedCollection", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "TransformedCollection", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "UnmodifiableBoundedCollection", True, "unmodifiableBoundedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.collection", "UnmodifiableCollection", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml new file mode 100644 index 00000000000..73509f98b1a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.iterators.model.yml @@ -0,0 +1,81 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformIterator + - ["org.apache.commons.collections.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractUntypedIteratorDecorator", True, "AbstractUntypedIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "AbstractUntypedIteratorDecorator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayIterator", True, "ArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ArrayListIterator", True, "ArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "BoundedIterator", True, "BoundedIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "getIterators", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "CollatingIterator", True, "setIterator", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "EnumerationIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "getEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "EnumerationIterator", True, "setEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "FilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterIterator", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator,Predicate)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "FilterListIterator", True, "setListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Collection)", "", "Argument[0].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "IteratorChain", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorChain", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "IteratorEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorEnumeration", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "IteratorIterable", True, "IteratorIterable", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ListIteratorWrapper", True, "ListIteratorWrapper", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "LoopingIterator", True, "LoopingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "LoopingListIterator", True, "LoopingListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayIterator", True, "ObjectArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ObjectArrayListIterator", True, "ObjectArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "PeekingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "element", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PeekingIterator", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PermutationIterator", True, "PermutationIterator", "", "", "Argument[0].Element", "Argument[-1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "PushbackIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "pushback", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "PushbackIterator", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ReverseListIterator", True, "ReverseListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SingletonIterator", True, "SingletonIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SingletonListIterator", True, "SingletonListIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "SkippingIterator", True, "SkippingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UniqueFilterIterator", True, "UniqueFilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableIterator", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableListIterator", True, "umodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml new file mode 100644 index 00000000000..d2c3e5652b5 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.keyvalue.model.yml @@ -0,0 +1,60 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "MultiKey", "(Object[],boolean)", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "MultiKey", True, "getKeys", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml new file mode 100644 index 00000000000..5fd3b418248 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.list.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedList + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "getFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "getLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "removeFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractLinkedList", True, "removeLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractListDecorator", True, "AbstractListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "AbstractSerializableListDecorator", True, "AbstractSerializableListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "CursorableLinkedList", True, "CursorableLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "CursorableLinkedList", True, "cursor", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "FixedSizeList", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "GrowthList", True, "growthList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "LazyList", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "NodeCachingLinkedList", True, "NodeCachingLinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "PredicatedList", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "SetUniqueList", True, "asSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "SetUniqueList", True, "setUniqueList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "TransformedList", True, "transformingList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.list", "TreeList", True, "TreeList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "UnmodifiableList", True, "UnmodifiableList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.list", "UnmodifiableList", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml new file mode 100644 index 00000000000..4e0ed31d72f --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.map.model.yml @@ -0,0 +1,134 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap + - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "CompositeMap", True, "removeComposited", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "DefaultedMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "DefaultedMap", True, "defaultedMap", "(Map,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LRUMap", True, "get", "(Object,boolean)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "LinkedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "keyList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "put", "", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "setValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "ListOrderedMap", True, "valueList", "", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[0..1]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[0..2]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[0..3]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..4]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[5]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiKeyMap", True, "removeMultiKey", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "getCollection", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "iterator", "(Object)", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "MultiValueMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "SingletonMap", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.model.yml b/java/ql/lib/ext/org.apache.commons.collections.model.yml new file mode 100644 index 00000000000..2df5f5772a4 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.model.yml @@ -0,0 +1,377 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + # Note that when lambdas are supported we should have more models for populateMap + # Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform + # Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator + - ["org.apache.commons.collections", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "ArrayStack", True, "push", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Bag", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "Bag", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "transformingBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "transformingSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BagUtils", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "BidiMap", True, "removeValue", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Enumeration)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "addIgnoreNull", "", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "collate", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "extractSingleton", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "getCardinalityMap", "", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "permutations", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[3].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `CollectionUtils.transformingCollection` does not transform existing list elements + - ["org.apache.commons.collections", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "CollectionUtils", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "EnumerationUtils", True, "toList", "(StringTokenizer)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Object[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "append", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "asEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "collate", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "eval", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "limit", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "loop", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "reverse", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "skip", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "toList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "unique", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "unmodifiable", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Get", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "boundedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[3].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "chainedIterable", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "filteredIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "loopingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "reversedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "skippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "uniqueIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "unmodifiableIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "arrayIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "arrayListIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asEnumeration", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "asMultipleUseIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "boundedIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Collection)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "chainedIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "filteredIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "filteredListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "getIterator", "", "", "Argument[0].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "loopingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "loopingListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "singletonIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "singletonListIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "skippingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "IteratorUtils", True, "zippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "KeyValue", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "KeyValue", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "defaultIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "defaultIfNull", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.lazyList` does not transform existing list elements + - ["org.apache.commons.collections", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "select", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "selectRejected", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.transformedList` does not transform existing list elements + - ["org.apache.commons.collections", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that MapIterator implements Iterator, so it iterates over the keys of the map. + # In order for the models of Iterator to work we have to use Element instead of MapKey for key data. + - ["org.apache.commons.collections", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapIterator", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getMap", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getMap", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getObject", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getObject", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getString", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "getString", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "invertMap", "", "", "Argument[0].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "invertMap", "", "", "Argument[0].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "populateMap", "(Map,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "populateMap", "(MultiMap,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "safeAddToMap", "", "", "Argument[1]", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "safeAddToMap", "", "", "Argument[2]", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "toMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "toMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getCollection", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsBag", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsList", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "getValuesAsSet", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "entrySet", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSet$Entry", True, "getElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiSetUtils", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "keySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "keys", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "remove", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "MultiValuedMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "OrderedIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "firstKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "lastKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "nextKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "OrderedMap", True, "previousKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Put", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "QueueUtils", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "difference", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "hashSet", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "orderedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "synchronizedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "synchronizedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "transformedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "createIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SetUtils$SetView", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections", "SortedBag", True, "first", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SortedBag", True, "last", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "Trie", True, "prefixMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "Trie", True, "prefixMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml new file mode 100644 index 00000000000..97ad092bc08 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.multimap.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedMultiValuedMap + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml b/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml new file mode 100644 index 00000000000..4423d4b1f91 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.multiset.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections.multiset", "HashMultiSet", True, "HashMultiSet", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "PredicatedMultiSet", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "SynchronizedMultiSet", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.multiset", "UnmodifiableMultiSet", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml b/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml new file mode 100644 index 00000000000..f149889197e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.properties.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(ClassLoader,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(File)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections.properties", "AbstractPropertiesFactory", True, "load", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml new file mode 100644 index 00000000000..3a88fbf5fa4 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.queue.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedQueue + - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "SynchronizedQueue", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "TransformedQueue", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.queue", "UnmodifiableQueue", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml new file mode 100644 index 00000000000..c6288adf72c --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.set.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedNavigableSet + - ["org.apache.commons.collections.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "CompositeSet", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "CompositeSet", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "addComposited", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "getSets", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "add", "", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "addAll", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "asList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "listOrderedSet", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "ListOrderedSet", True, "listOrderedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "MapBackedSet", True, "mapBackedSet", "", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedNavigableSet", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedSet", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "PredicatedSortedSet", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedNavigableSet", True, "transformingNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedSet", True, "transformingSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "TransformedSortedSet", True, "transformingSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableNavigableSet", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableSet", True, "unmodifiableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections.set", "UnmodifiableSortedSet", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml new file mode 100644 index 00000000000..65cc1a66fdf --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.splitmap.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap + - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml new file mode 100644 index 00000000000..c58ca641902 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections.trie.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "AbstractPatriciaTrie", True, "selectValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml new file mode 100644 index 00000000000..9df2c7aba94 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.bag.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag + - ["org.apache.commons.collections4.bag", "AbstractBagDecorator", True, "AbstractBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "AbstractMapBag", "", "", "Argument[0].MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractMapBag", True, "getMap", "", "", "Argument[-1].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bag", "AbstractSortedBagDecorator", True, "AbstractSortedBagDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionBag", True, "CollectionBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionBag", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionSortedBag", True, "CollectionSortedBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "CollectionSortedBag", True, "collectionSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "HashBag", True, "HashBag", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "PredicatedBag", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "PredicatedSortedBag", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "SynchronizedBag", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "SynchronizedSortedBag", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TransformedBag", True, "transformedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TransformedSortedBag", True, "transformedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "TreeBag", True, "TreeBag", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "UnmodifiableBag", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.bag", "UnmodifiableSortedBag", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml new file mode 100644 index 00000000000..1a6a3cbab9e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.bidimap.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections4.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractBidiMapDecorator", True, "AbstractBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[1].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapKey", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractDualBidiMap", True, "AbstractDualBidiMap", "", "", "Argument[2].MapValue", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractOrderedBidiMapDecorator", True, "AbstractOrderedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "AbstractSortedBidiMapDecorator", True, "AbstractSortedBidiMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualHashBidiMap", True, "DualHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualLinkedHashBidiMap", True, "DualLinkedHashBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "DualTreeBidiMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "DualTreeBidiMap", True, "inverseSortedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "TreeBidiMap", True, "TreeBidiMap", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableBidiMap", True, "unmodifiableBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "inverseOrderedBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableOrderedBidiMap", True, "unmodifiableOrderedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.bidimap", "UnmodifiableSortedBidiMap", True, "unmodifiableSortedBidiMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml new file mode 100644 index 00000000000..7533350620b --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.collection.model.yml @@ -0,0 +1,46 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedCollection + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "AbstractCollectionDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "decorated", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "AbstractCollectionDecorator", True, "setCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "CompositeCollection", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection,Collection)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "addComposited", "(Collection[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "getCollections", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection", True, "toCollection", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "CompositeCollection$CollectionMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "IndexedCollection", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "nonUniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "uniqueIndexedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "IndexedCollection", True, "values", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "addAll", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "createPredicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "PredicatedCollection$Builder", True, "rejectedElements", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "SynchronizedCollection", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "TransformedCollection", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "UnmodifiableBoundedCollection", True, "unmodifiableBoundedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.collection", "UnmodifiableCollection", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml new file mode 100644 index 00000000000..8fe0e4578f9 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.iterators.model.yml @@ -0,0 +1,81 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformIterator + - ["org.apache.commons.collections4.iterators", "AbstractIteratorDecorator", True, "AbstractIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "AbstractListIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractListIteratorDecorator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "AbstractMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractMapIteratorDecorator", True, "getMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "AbstractOrderedMapIteratorDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractOrderedMapIteratorDecorator", True, "getOrderedMapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractUntypedIteratorDecorator", True, "AbstractUntypedIteratorDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "AbstractUntypedIteratorDecorator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayIterator", True, "ArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ArrayListIterator", True, "ArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "BoundedIterator", True, "BoundedIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "CollatingIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "getIterators", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "CollatingIterator", True, "setIterator", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "EnumerationIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "getEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "EnumerationIterator", True, "setEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "FilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterIterator", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "FilterListIterator", "(ListIterator,Predicate)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "getListIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "FilterListIterator", True, "setListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Collection)", "", "Argument[0].Element.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "IteratorChain", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorChain", True, "addIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "IteratorEnumeration", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "getIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorEnumeration", True, "setIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "IteratorIterable", True, "IteratorIterable", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ListIteratorWrapper", True, "ListIteratorWrapper", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "LoopingIterator", True, "LoopingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "LoopingListIterator", True, "LoopingListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayIterator", True, "ObjectArrayIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayIterator", True, "getArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ObjectArrayListIterator", True, "ObjectArrayListIterator", "", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "PeekingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "element", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PeekingIterator", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PermutationIterator", True, "PermutationIterator", "", "", "Argument[0].Element", "Argument[-1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "PushbackIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "pushback", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "PushbackIterator", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ReverseListIterator", True, "ReverseListIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SingletonIterator", True, "SingletonIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SingletonListIterator", True, "SingletonListIterator", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "SkippingIterator", True, "SkippingIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UniqueFilterIterator", True, "UniqueFilterIterator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableIterator", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableListIterator", True, "umodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableMapIterator", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "UnmodifiableOrderedMapIterator", True, "unmodifiableOrderedMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.iterators", "ZippingIterator", True, "ZippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml new file mode 100644 index 00000000000..e662c6348bd --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.keyvalue.model.yml @@ -0,0 +1,60 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "AbstractKeyValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setKey", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractKeyValue", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntry", True, "AbstractMapEntry", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "AbstractMapEntryDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "AbstractMapEntryDecorator", True, "getMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "DefaultKeyValue", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultKeyValue", True, "toMapEntry", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "DefaultMapEntry", True, "DefaultMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[2]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "MultiKey", "(Object[],boolean)", "", "Argument[0].ArrayElement", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "MultiKey", True, "getKeys", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "TiedMapEntry", True, "TiedMapEntry", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.keyvalue", "UnmodifiableMapEntry", True, "UnmodifiableMapEntry", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml new file mode 100644 index 00000000000..b0e01ed6929 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.list.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedList + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "AbstractLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addFirst", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "addLast", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "getFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "getLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "removeFirst", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractLinkedList", True, "removeLast", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractListDecorator", True, "AbstractListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "AbstractSerializableListDecorator", True, "AbstractSerializableListDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "CursorableLinkedList", True, "CursorableLinkedList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "CursorableLinkedList", True, "cursor", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "FixedSizeList", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "GrowthList", True, "growthList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "LazyList", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "NodeCachingLinkedList", True, "NodeCachingLinkedList", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "PredicatedList", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "SetUniqueList", True, "asSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "SetUniqueList", True, "setUniqueList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "TransformedList", True, "transformingList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "TreeList", True, "TreeList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "UnmodifiableList", True, "UnmodifiableList", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.list", "UnmodifiableList", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml new file mode 100644 index 00000000000..385f73050d5 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.map.model.yml @@ -0,0 +1,134 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap + - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractHashedMap", True, "AbstractHashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractLinkedMap", True, "AbstractLinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "AbstractMapDecorator", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractMapDecorator", True, "decorated", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractOrderedMapDecorator", True, "AbstractOrderedMapDecorator", "(OrderedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "AbstractSortedMapDecorator", True, "AbstractSortedMapDecorator", "(SortedMap)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CaseInsensitiveMap", True, "CaseInsensitiveMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map,Map,MapMutator)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[])", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "CompositeMap", "(Map[],MapMutator)", "", "Argument[0].ArrayElement.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "addComposited", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "CompositeMap", True, "removeComposited", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "DefaultedMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "DefaultedMap", True, "defaultedMap", "(Map,Object)", "", "Argument[1]", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapKey", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "EntrySetToMapIteratorAdapter", True, "EntrySetToMapIteratorAdapter", "", "", "Argument[0].Element.MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeMap", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "FixedSizeSortedMap", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "Flat3Map", True, "Flat3Map", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "HashedMap", True, "HashedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "LRUMap", "(Map,boolean)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LRUMap", True, "get", "(Object,boolean)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazyMap", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LazySortedMap", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "LinkedMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "LinkedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "asList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "get", "(int)", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "getValue", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "keyList", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "listOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "put", "", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "putAll", "", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "remove", "(int)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "setValue", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "ListOrderedMap", True, "valueList", "", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[0..1]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object)", "", "Argument[2]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[0..2]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object)", "", "Argument[3]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[0..3]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object)", "", "Argument[4]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[0..4]", "Argument[-1].MapKey.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "put", "(Object,Object,Object,Object,Object,Object)", "", "Argument[5]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiKeyMap", True, "removeMultiKey", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "getCollection", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "()", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "iterator", "(Object)", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "multiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "putAll", "(Object,Collection)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "MultiValueMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(ExpirationPolicy,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,Map)", "", "Argument[1].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PassiveExpiringMap", True, "PassiveExpiringMap", "(long,TimeUnit,Map)", "", "Argument[2].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedMap", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "PredicatedSortedMap", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Entry)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(KeyValue)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "SingletonMap", "(Object,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "SingletonMap", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "TransformedSortedMap", True, "transformingSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableEntrySet", True, "unmodifiableEntrySet", "", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableMap", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableOrderedMap", True, "unmodifiableOrderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.map", "UnmodifiableSortedMap", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.model.yml new file mode 100644 index 00000000000..218da08ca22 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.model.yml @@ -0,0 +1,377 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform + # Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, + # and when more general callable flow is supported we should model the package + # `org.apache.commons.collections4.sequence`. + # Note that when lambdas are supported we should have more models for populateMap + # Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform + # Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator + - ["org.apache.commons.collections4", "ArrayStack", True, "peek", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "pop", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "push", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "ArrayStack", True, "push", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Bag", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "Bag", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "collectionBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "predicatedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "predicatedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "synchronizedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "synchronizedSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "transformingBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "transformingSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "unmodifiableBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BagUtils", True, "unmodifiableSortedBag", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "inverseBidiMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "BidiMap", True, "removeValue", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Enumeration)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Iterable)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Iterator)", "", "Argument[1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addAll", "(Collection,Object[])", "", "Argument[1].ArrayElement", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "addIgnoreNull", "", "", "Argument[1]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "collate", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "extractSingleton", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Iterable,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Iterator,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Map,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "get", "(Object,int)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "getCardinalityMap", "", "", "Argument[0].Element", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "permutations", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "predicatedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[0].Element", "Argument[3].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "select", "(Iterable,Predicate,Collection,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[0].Element", "Argument[2].Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "selectRejected", "(Iterable,Predicate,Collection)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "synchronizedCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `CollectionUtils.transformingCollection` does not transform existing list elements + - ["org.apache.commons.collections4", "CollectionUtils", True, "transformingCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "CollectionUtils", True, "unmodifiableCollection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "toList", "(Enumeration)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "EnumerationUtils", True, "toList", "(StringTokenizer)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Object[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "append", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "asEnumeration", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "collate", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "collate", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "eval", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "filter", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "limit", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "loop", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "of", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "reverse", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "skip", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "toArray", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "toList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "unique", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "unmodifiable", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "FluentIterable", True, "zip", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "entrySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "entrySet", "", "", "Argument[-1].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "keySet", "()", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "remove", "(Object)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Get", True, "values", "()", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableGet", True, "mapIterator", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "boundedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable,Iterable,Iterable,Iterable)", "", "Argument[3].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "chainedIterable", "(Iterable[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Comparator,Iterable,Iterable)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "collatedIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "filteredIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "loopingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "reversedIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "skippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "uniqueIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "unmodifiableIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IterableUtils", True, "zippingIterable", "(Iterable,Iterable[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "arrayIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "arrayListIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asEnumeration", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "asMultipleUseIterable", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "boundedIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Collection)", "", "Argument[0].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "chainedIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Collection)", "", "Argument[1].Element.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "collatedIterator", "(Comparator,Iterator[])", "", "Argument[1].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "filteredIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "filteredListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "find", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "first", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "forEachButLast", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "get", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "getIterator", "", "", "Argument[0].MapValue", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "loopingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "loopingListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "peekingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "pushbackIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "singletonIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "singletonListIterator", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "skippingIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "toString", "", "", "Argument[4]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableListIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "unmodifiableMapIterator", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator,Iterator,Iterator)", "", "Argument[2].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "IteratorUtils", True, "zippingIterator", "(Iterator[])", "", "Argument[0].ArrayElement.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "KeyValue", True, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "KeyValue", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "defaultIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "defaultIfNull", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "fixedSizeList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.lazyList` does not transform existing list elements + - ["org.apache.commons.collections4", "ListUtils", True, "lazyList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(CharSequence,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "longestCommonSubsequence", "(List,List,Equator)", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "partition", "", "", "Argument[0].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "predicatedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "removeAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "retainAll", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "select", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "selectRejected", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "subtract", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "sum", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "synchronizedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that `ListUtils.transformedList` does not transform existing list elements + - ["org.apache.commons.collections4", "ListUtils", True, "transformedList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "ListUtils", True, "unmodifiableList", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + # Note that MapIterator implements Iterator, so it iterates over the keys of the map. + # In order for the models of Iterator to work we have to use Element instead of MapKey for key data. + - ["org.apache.commons.collections4", "MapIterator", True, "getKey", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "setValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapIterator", True, "setValue", "", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "fixedSizeSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getMap", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getMap", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getObject", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getObject", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getString", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "getString", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "invertMap", "", "", "Argument[0].MapKey", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "invertMap", "", "", "Argument[0].MapValue", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "iterableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazyMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "lazySortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "multiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "orderedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "populateMap", "(Map,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "populateMap", "(MultiMap,Iterable,Transformer)", "", "Argument[1].Element", "Argument[0].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "predicatedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "putAll", "", "", "Argument[1].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "safeAddToMap", "", "", "Argument[1]", "Argument[0].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "safeAddToMap", "", "", "Argument[2]", "Argument[0].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "synchronizedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "toMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "toMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "transformedSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MapUtils", True, "unmodifiableSortedMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getCollection", "", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsBag", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsList", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "getValuesAsSet", "", "", "Argument[0].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "transformedMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiMapUtils", True, "unmodifiableMultiValuedMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "add", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "entrySet", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet", True, "uniqueSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSet$Entry", True, "getElement", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiSetUtils", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "asMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "entries", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "get", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "keySet", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "keys", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "mapIterator", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "putAll", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "remove", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "MultiValuedMap", True, "values", "", "", "Argument[-1].MapValue.Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedIterator", True, "previous", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "firstKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "lastKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "nextKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "OrderedMap", True, "previousKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "putAll", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Put", True, "putAll", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "QueueUtils", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "difference", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "disjunction", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "disjunction", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "emptyIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "hashSet", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "intersection", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "intersection", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "orderedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "synchronizedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "synchronizedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "transformedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "union", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "union", "", "", "Argument[1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSet", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "copyInto", "", "", "Argument[-1].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "createIterator", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SetUtils$SetView", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4", "SortedBag", True, "first", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SortedBag", True, "last", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "readableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "SplitMapUtils", True, "writableMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "Trie", True, "prefixMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "Trie", True, "prefixMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4", "TrieUtils", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml new file mode 100644 index 00000000000..6bd01379d9e --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.multimap.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedMultiValuedMap + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "ArrayListValuedHashMap", True, "ArrayListValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "HashSetValuedHashMap", True, "HashSetValuedHashMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "TransformedMultiValuedMap", True, "transformingMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.multimap", "UnmodifiableMultiValuedMap", True, "unmodifiableMultiValuedMap", "(MultiValuedMap)", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml new file mode 100644 index 00000000000..c3da82c1b7a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.multiset.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections4.multiset", "HashMultiSet", True, "HashMultiSet", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "PredicatedMultiSet", True, "predicatedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "SynchronizedMultiSet", True, "synchronizedMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.multiset", "UnmodifiableMultiSet", True, "unmodifiableMultiSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml new file mode 100644 index 00000000000..9187922313a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.properties.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(ClassLoader,String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(File)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.collections4.properties", "AbstractPropertiesFactory", True, "load", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml new file mode 100644 index 00000000000..b2cab2a0594 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.queue.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedQueue + - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "CircularFifoQueue", "(Collection)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "CircularFifoQueue", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.queue", "PredicatedQueue", True, "predicatedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "SynchronizedQueue", True, "synchronizedQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "TransformedQueue", True, "transformingQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.queue", "UnmodifiableQueue", True, "unmodifiableQueue", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml new file mode 100644 index 00000000000..deafbdffaaf --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.set.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedNavigableSet + - ["org.apache.commons.collections4.set", "AbstractNavigableSetDecorator", True, "AbstractNavigableSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "AbstractSetDecorator", True, "AbstractSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "AbstractSortedSetDecorator", True, "AbstractSortedSetDecorator", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "CompositeSet", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "CompositeSet", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set,Set)", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "addComposited", "(Set[])", "", "Argument[0].ArrayElement.Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "getSets", "", "", "Argument[-1].Element", "ReturnValue.Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet", True, "toSet", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "add", "", "", "Argument[2]", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[0].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "CompositeSet$SetMutator", True, "addAll", "", "", "Argument[2].Element", "Argument[1].Element.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "add", "", "", "Argument[1]", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "addAll", "", "", "Argument[1].Element", "Argument[-1].Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "asList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "get", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "listOrderedSet", "(List)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "ListOrderedSet", True, "listOrderedSet", "(Set)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "MapBackedSet", True, "mapBackedSet", "", "", "Argument[0].MapKey", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedNavigableSet", True, "predicatedNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedSet", True, "predicatedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "PredicatedSortedSet", True, "predicatedSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedNavigableSet", True, "transformingNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedSet", True, "transformingSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "TransformedSortedSet", True, "transformingSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableNavigableSet", True, "unmodifiableNavigableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableSet", True, "unmodifiableSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.apache.commons.collections4.set", "UnmodifiableSortedSet", True, "unmodifiableSortedSet", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml new file mode 100644 index 00000000000..7190dac37a0 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.splitmap.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap + - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "AbstractIterableGetMapDecorator", True, "AbstractIterableGetMapDecorator", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.splitmap", "TransformedSplitMap", True, "transformingMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml new file mode 100644 index 00000000000..7c7195d54dc --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.collections4.trie.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Note that when lambdas are supported we should have more models for TransformedSplitMap + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "select", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "selectKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "AbstractPatriciaTrie", True, "selectValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "PatriciaTrie", True, "PatriciaTrie", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.apache.commons.collections4.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.collections4.trie", "UnmodifiableTrie", True, "unmodifiableTrie", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml new file mode 100644 index 00000000000..d00be2099de --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + # Models that are not yet auto generated or where the generated summaries will + # be ignored. + # Note that if a callable has any handwritten summary, all generated summaries + # will be ignored for that callable. + - ["org.apache.commons.io", "IOUtils", False, "toBufferedInputStream", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "toByteArray", "(Reader,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "writeLines", "(Collection,String,Writer)", "", "Argument[0].Element", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.io", "IOUtils", True, "writeLines", "(Collection,String,Writer)", "", "Argument[1]", "Argument[2]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.jexl2.model.yml b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml new file mode 100644 index 00000000000..2389ae1d183 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.jexl2", "Expression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(JexlContext,Object,String,Object)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "prepare", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Template", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.jexl3.model.yml b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml new file mode 100644 index 00000000000..206eb79420a --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.jexl3", "Expression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "prepare", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Template", False, "evaluate", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "callable", "", "", "Argument[-1]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "execute", "", "", "Argument[-1]", "jexl", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml new file mode 100644 index 00000000000..88d2bbe4790 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.builder.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[],boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "append", "(java.lang.String,java.lang.Object[],boolean)", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendAsObjectToString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendSuper", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendSuper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendToString", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "appendToString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "getStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.builder", "ToStringBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.model.yml new file mode 100644 index 00000000000..ad2332fe007 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.model.yml @@ -0,0 +1,217 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.lang3", "RegExUtils", False, "removeAll", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeFirst", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removePattern", "(String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "(String,String,String)", "", "Argument[1]", "regex-use", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "", "", "Argument[2]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(boolean[],boolean)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(byte[],byte)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(char[],char)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(double[],double)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(float[],float)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(int[],int)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(java.lang.Object[],java.lang.Object)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(long[],long)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "add", "(short[],short)", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addAll", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addFirst", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "addFirst", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "clone", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "get", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "get", "(java.lang.Object[],int,java.lang.Object)", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "insert", "", "", "Argument[1..2].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "nullToEmpty", "(java.lang.Object[],java.lang.Class)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "nullToEmpty", "(java.lang.String[])", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "remove", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAll", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAllOccurences", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeAllOccurrences", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeElement", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "removeElements", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "subarray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toMap", "", "", "Argument[0].ArrayElement.MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toObject", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toPrimitive", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ArrayUtils", False, "toPrimitive", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST_BYTE", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "CONST_SHORT", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "clone", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "cloneIfPossible", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "defaultIfNull", "", "", "Argument[0..1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "firstNonNull", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "getIfNull", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "median", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "min", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "mode", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "requireNonEmpty", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "ObjectUtils", False, "toString", "(Object,String)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removeFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "removePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replaceFirst", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "RegExUtils", False, "replacePattern", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringEscapeUtils", False, "escapeJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "(java.lang.String,java.lang.String,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviate", "(java.lang.String,java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviateMiddle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "abbreviateMiddle", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissing", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissing", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissingIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "appendIfMissingIgnoreCase", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "capitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "center", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "center", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chomp", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chomp", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "chop", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultIfBlank", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultIfEmpty", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "defaultString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "deleteWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "difference", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "firstNonBlank", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "firstNonEmpty", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getBytes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getCommonPrefix", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getDigits", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getIfBlank", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "getIfEmpty", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(char[],char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(char[],char,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,char)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,java.lang.String)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Iterable,java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],char)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],char,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String,int,int)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.lang.Object[],java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,char)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,java.lang.String)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.Iterator,java.lang.String)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,char,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,java.lang.String,int,int)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "join", "(java.util.List,java.lang.String,int,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "joinWith", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "joinWith", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "left", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "leftPad", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "leftPad", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "lowerCase", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "lowerCase", "(java.lang.String,java.util.Locale)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "mid", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "normalizeSpace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "overlay", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "overlay", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissing", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissing", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissingIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "prependIfMissingIgnoreCase", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeEnd", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeEndIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeStart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "removeStartIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "repeat", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "repeat", "(java.lang.String,java.lang.String,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceChars", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceChars", "(java.lang.String,java.lang.String,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEach", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEach", "", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEachRepeatedly", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceEachRepeatedly", "", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceFirst", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceIgnoreCase", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnce", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnce", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnceIgnoreCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replaceOnceIgnoreCase", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replacePattern", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "replacePattern", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "reverse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "reverseDelimited", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "right", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rightPad", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rightPad", "(java.lang.String,int,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "rotate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "split", "(java.lang.String,java.lang.String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByCharacterType", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByCharacterTypeCamelCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByWholeSeparator", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitByWholeSeparatorPreserveAllTokens", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "splitPreserveAllTokens", "(java.lang.String,java.lang.String,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "strip", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "strip", "(java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripAccents", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripAll", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripEnd", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripStart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripToEmpty", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "stripToNull", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substring", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringAfter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringAfterLast", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBefore", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBeforeLast", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringBetween", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "substringsBetween", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toCodePoints", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toEncodedString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toRootLowerCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toRootUpperCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trim", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trimToEmpty", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "trimToNull", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "truncate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "uncapitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "unwrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "upperCase", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "upperCase", "(java.lang.String,java.util.Locale)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "valueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrap", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrap", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrapIfMissing", "(java.lang.String,char)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3", "StringUtils", False, "wrapIfMissing", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml new file mode 100644 index 00000000000..48816a4a9e2 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.mutable.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.lang3.mutable", "Mutable", True, "getValue", "", "", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.mutable", "Mutable", True, "setValue", "", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "value", "manual"] + - ["org.apache.commons.lang3.mutable", "MutableObject", False, "MutableObject", "", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value]", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml new file mode 100644 index 00000000000..e11dfbaa34d --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.text.model.yml @@ -0,0 +1,160 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.lang3.text", "StrBuilder", False, "StrBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "append", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "appendln", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replace", "(org.apache.commons.lang3.text.StrMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.text", "StrLookup", False, "lookup", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrLookup", False, "mapLookup", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "StrSubstitutor", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "StrSubstitutor", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replace", "(org.apache.commons.lang3.text.StrBuilder,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuffer,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(java.lang.StringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(org.apache.commons.lang3.text.StrBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "replaceIn", "(org.apache.commons.lang3.text.StrBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrSubstitutor", False, "setVariableResolver", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "StrTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "StrTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalizeFully", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "capitalizeFully", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "initials", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "initials", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "uncapitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "uncapitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.lang3.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml b/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml new file mode 100644 index 00000000000..ebd11508343 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.lang3.tuple.model.yml @@ -0,0 +1,52 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "ImmutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "ImmutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "left", "", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutablePair", False, "right", "", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "ImmutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "ImmutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "MutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "MutablePair", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setLeft", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setRight", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutablePair", False, "setValue", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "MutableTriple", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setLeft", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setMiddle", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "MutableTriple", False, "setRight", "", "", "Argument[0]", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getKey", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getKey", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getValue", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", True, "getValue", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Pair", False, "of", "(java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getLeft", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getMiddle", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getMiddle", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", True, "getRight", "", "", "Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[0]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[1]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle]", "value", "manual"] + - ["org.apache.commons.lang3.tuple", "Triple", False, "of", "(java.lang.Object,java.lang.Object,java.lang.Object)", "", "Argument[2]", "ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right]", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.logging.model.yml b/java/ql/lib/ext/org.apache.commons.logging.model.yml new file mode 100644 index 00000000000..8f40e26f2a1 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.logging.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.logging", "Log", True, "debug", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "error", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "fatal", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "trace", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "warn", "", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml b/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml new file mode 100644 index 00000000000..790c7640d9b --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.ognl.enhance.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.ognl.enhance", "ExpressionAccessor", True, "get", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl.enhance", "ExpressionAccessor", True, "set", "", "", "Argument[-1]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.ognl.model.yml b/java/ql/lib/ext/org.apache.commons.ognl.model.yml new file mode 100644 index 00000000000..9b00a781f53 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.ognl.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.commons.ognl", "Node", True, "getValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Node", True, "setValue", "", "", "Argument[-1]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Ognl", False, "getValue", "", "", "Argument[0]", "ognl-injection", "manual"] + - ["org.apache.commons.ognl", "Ognl", False, "setValue", "", "", "Argument[0]", "ognl-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml b/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml new file mode 100644 index 00000000000..b89855197f1 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.text.lookup.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.text.lookup", "StringLookup", True, "lookup", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text.lookup", "StringLookupFactory", False, "mapStringLookup", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.text.model.yml b/java/ql/lib/ext/org.apache.commons.text.model.yml new file mode 100644 index 00000000000..c0618224fe4 --- /dev/null +++ b/java/ql/lib/ext/org.apache.commons.text.model.yml @@ -0,0 +1,275 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.commons.text", "StrBuilder", False, "StrBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "append", "(org.apache.commons.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "appendln", "(org.apache.commons.text.StrBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replace", "(org.apache.commons.text.StrMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "StrTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StrTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "StringSubstitutor", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "StringSubstitutor", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Map,java.lang.String,java.lang.String)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.Object,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.String,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.StringBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replace", "(org.apache.commons.text.TextStringBuilder,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuffer,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(java.lang.StringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "replaceIn", "(org.apache.commons.text.TextStringBuilder,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "StringSubstitutor", False, "setVariableResolver", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "StringTokenizer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getCSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTSVInstance", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTokenArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "getTokenList", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "previous", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "previousToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "reset", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "StringTokenizer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "TextStringBuilder", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "TextStringBuilder", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.CharSequence,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.nio.CharBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(java.nio.CharBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "append", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Iterator)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadLeft", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendFixedWidthPadRight", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendNewLine", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendNull", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendPadding", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendSeparator", "(java.lang.String,java.lang.String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Iterable,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Iterator,String)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendWithSeparators", "(Object[],String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(char[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.String,java.lang.Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(java.lang.StringBuilder,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "appendln", "(org.apache.commons.text.TextStringBuilder)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "asReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "asTokenizer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "delete", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "deleteFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "ensureCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(char[])", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "getChars", "(int,int,char[],int)", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "insert", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "leftString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "midString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "minimizeCapacity", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "readFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "(int,int,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replace", "(org.apache.commons.text.matcher.StringMatcher,java.lang.String,int,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceAll", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "replaceFirst", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "reverse", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "rightString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setCharAt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setLength", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setNewLineText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "setNullText", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "substring", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toStringBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "toStringBuilder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "TextStringBuilder", False, "trim", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "abbreviate", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "abbreviate", "", "", "Argument[3]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalizeFully", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "capitalizeFully", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "initials", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "initials", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "swapCase", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "uncapitalize", "(java.lang.String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "uncapitalize", "(java.lang.String,char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.apache.commons.text", "WordUtils", False, "wrap", "(java.lang.String,int,java.lang.String,boolean,java.lang.String)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml new file mode 100644 index 00000000000..14b580383d3 --- /dev/null +++ b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.directory.ldap.client.api", "LdapConnection", True, "search", "", "", "Argument[0..2]", "ldap", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.function.model.yml b/java/ql/lib/ext/org.apache.hc.core5.function.model.yml new file mode 100644 index 00000000000..2763da9cd3d --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.function.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.function", "Supplier", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml new file mode 100644 index 00000000000..2b7b1a4eaf3 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.io.entity.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.http.io.entity", "BasicHttpEntity", True, "BasicHttpEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "BufferedHttpEntity", True, "BufferedHttpEntity", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "ByteArrayEntity", True, "ByteArrayEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "parse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "toByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "EntityUtils", True, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "create", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "createGzipped", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "createUrlEncoded", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "gzip", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntities", True, "withTrailers", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "HttpEntityWrapper", True, "HttpEntityWrapper", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "InputStreamEntity", True, "InputStreamEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.io.entity", "StringEntity", True, "StringEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml new file mode 100644 index 00000000000..8183cb9a3a7 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.io.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.apache.hc.core5.http.io", "HttpRequestHandler", True, "handle", "(ClassicHttpRequest,ClassicHttpResponse,HttpContext)", "", "Parameter[0]", "remote", "manual"] + - ["org.apache.hc.core5.http.io", "HttpServerRequestHandler", True, "handle", "(ClassicHttpRequest,ResponseTrigger,HttpContext)", "", "Parameter[0]", "remote", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml new file mode 100644 index 00000000000..bf8ab791ccf --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.http.message", "RequestLine", True, "RequestLine", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "RequestLine", "(String,String,ProtocolVersion)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http.message", "RequestLine", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml new file mode 100644 index 00000000000..c0fcdc852dc --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml @@ -0,0 +1,30 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.http", "EntityDetails", True, "getContentEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "EntityDetails", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "EntityDetails", True, "getTrailerNames", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntity", True, "getContent", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntity", True, "getTrailers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "getEntity", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getAuthority", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getRequestUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getFirstHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeaders", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getHeaders", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "getLastHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "headerIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "MessageHeaders", True, "headerIterator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "NameValuePair", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.http", "NameValuePair", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.net.model.yml b/java/ql/lib/ext/org.apache.hc.core5.net.model.yml new file mode 100644 index 00000000000..e16c8b150c3 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.net.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.net", "URIAuthority", True, "getHostName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.net", "URIAuthority", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.util.model.yml b/java/ql/lib/ext/org.apache.hc.core5.util.model.yml new file mode 100644 index 00000000000..2023ad04f6e --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.core5.util.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.hc.core5.util", "Args", True, "containsNoBlanks", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notBlank", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(Collection,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notEmpty", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "Args", True, "notNull", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "ByteArrayBuffer", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(ByteArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "subSequence", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "substring", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "substringTrimmed", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "toCharArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.hc.core5.util", "CharArrayBuffer", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.client.methods.model.yml b/java/ql/lib/ext/org.apache.http.client.methods.model.yml new file mode 100644 index 00000000000..c90298bddf8 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.client.methods.model.yml @@ -0,0 +1,23 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.http.client.methods", "HttpDelete", False, "HttpDelete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpGet", False, "HttpGet", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpHead", False, "HttpHead", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpOptions", False, "HttpOptions", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPatch", False, "HttpPatch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPost", False, "HttpPost", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpPut", False, "HttpPut", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpRequestBase", True, "setURI", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpTrace", False, "HttpTrace", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "get", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "head", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "options", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "patch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "post", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "setUri", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "trace", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.entity.model.yml b/java/ql/lib/ext/org.apache.http.entity.model.yml new file mode 100644 index 00000000000..4105b55a634 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.entity.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http.entity", "BasicHttpEntity", True, "setContent", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.entity", "BufferedHttpEntity", True, "BufferedHttpEntity", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "ByteArrayEntity", True, "ByteArrayEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.entity", "HttpEntityWrapper", True, "HttpEntityWrapper", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "InputStreamEntity", True, "InputStreamEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.entity", "StringEntity", True, "StringEntity", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.message.model.yml b/java/ql/lib/ext/org.apache.http.message.model.yml new file mode 100644 index 00000000000..da798c12017 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.message.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http.message", "BasicRequestLine", False, "BasicRequestLine", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.model.yml b/java/ql/lib/ext/org.apache.http.model.yml new file mode 100644 index 00000000000..25c5847ad0a --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.model.yml @@ -0,0 +1,42 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.apache.http", "HttpEntity", False, "getContent", "()", "", "ReturnValue", "remote", "manual"] + - ["org.apache.http", "HttpMessage", False, "getParams", "()", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.http", "HttpRequest", True, "setURI", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http", "HttpResponse", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http", "Header", True, "getElements", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameter", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameterByName", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getParameters", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderElement", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HeaderIterator", True, "nextHeader", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContent", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContentEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntity", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpEntityEnclosingRequest", True, "getEntity", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getAllHeaders", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getFirstHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getHeaders", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getLastHeader", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "getParams", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "headerIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpMessage", True, "headerIterator", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "HttpRequest", True, "getRequestLine", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "NameValuePair", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "NameValuePair", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getMethod", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "getUri", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http", "RequestLine", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.params.model.yml b/java/ql/lib/ext/org.apache.http.params.model.yml new file mode 100644 index 00000000000..35cd5b5c8a3 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.params.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http.params", "HttpParams", True, "getDoubleParameter", "(String,double)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getDoubleParameter", "(String,double)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getIntParameter", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getIntParameter", "(String,int)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getLongParameter", "(String,long)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getLongParameter", "(String,long)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.http.params", "HttpParams", True, "getParameter", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.protocol.model.yml b/java/ql/lib/ext/org.apache.http.protocol.model.yml new file mode 100644 index 00000000000..c5de98c8c68 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.protocol.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.apache.http.protocol", "HttpRequestHandler", True, "handle", "(HttpRequest,HttpResponse,HttpContext)", "", "Parameter[0]", "remote", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.util.model.yml b/java/ql/lib/ext/org.apache.http.util.model.yml new file mode 100644 index 00000000000..34fb87b5cb9 --- /dev/null +++ b/java/ql/lib/ext/org.apache.http.util.model.yml @@ -0,0 +1,41 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.http.util", "EntityUtils", True, "updateEntity", "(HttpResponse,HttpEntity)", "", "Argument[1]", "xss", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http.util", "Args", True, "containsNoBlanks", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notBlank", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notEmpty", "(CharSequence,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notEmpty", "(Collection,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "Args", True, "notNull", "(Object,String)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "ByteArrayBuffer", True, "toByteArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(ByteArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(CharArrayBuffer,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "append", "(char[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "subSequence", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "substring", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "substringTrimmed", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "toCharArray", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "CharArrayBuffer", True, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getAsciiBytes", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getAsciiString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getBytes", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EncodingUtils", True, "getString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "getContentCharSet", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "getContentMimeType", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "toByteArray", "(HttpEntity)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml new file mode 100644 index 00000000000..05dac3d7f10 --- /dev/null +++ b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml @@ -0,0 +1,72 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "delete", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "insert", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "run", "(String)", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectAll", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectOne", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "update", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "DELETE_FROM", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FETCH_FIRST_ROWS_ONLY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "FROM", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "GROUP_BY", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "HAVING", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INNER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INSERT_INTO", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INTO_COLUMNS", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "INTO_VALUES", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LEFT_OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "LIMIT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OFFSET", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OFFSET_ROWS", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "ORDER_BY", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "RIGHT_OUTER_JOIN", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SELECT_DISTINCT", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "SET", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "UPDATE", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "VALUES", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "WHERE", "(String[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.apache.ibatis.jdbc", "AbstractSQL", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.log4j.model.yml b/java/ql/lib/ext/org.apache.log4j.model.yml new file mode 100644 index 00000000000..309f238111b --- /dev/null +++ b/java/ql/lib/ext/org.apache.log4j.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.log4j", "Category", True, "assertLog", "", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "debug", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "error", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "fatal", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "forcedLog", "", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "info", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "l7dlog", "(Priority,String,Object[],Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(String,Priority,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "warn", "", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.apache.logging.log4j.model.yml b/java/ql/lib/ext/org.apache.logging.log4j.model.yml new file mode 100644 index 00000000000..5ffe10450a0 --- /dev/null +++ b/java/ql/lib/ext/org.apache.logging.log4j.model.yml @@ -0,0 +1,376 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.apache.shiro.codec.model.yml b/java/ql/lib/ext/org.apache.shiro.codec.model.yml new file mode 100644 index 00000000000..f0a40c8549b --- /dev/null +++ b/java/ql/lib/ext/org.apache.shiro.codec.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.shiro.codec", "Base64", False, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.apache.shiro.jndi.model.yml b/java/ql/lib/ext/org.apache.shiro.jndi.model.yml new file mode 100644 index 00000000000..6da50e9d0b6 --- /dev/null +++ b/java/ql/lib/ext/org.apache.shiro.jndi.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.shiro.jndi", "JndiTemplate", False, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.app.model.yml b/java/ql/lib/ext/org.apache.velocity.app.model.yml new file mode 100644 index 00000000000..1afc328b882 --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.app.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.velocity.app", "Velocity", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.app", "Velocity", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml new file mode 100644 index 00000000000..a8f740a2301 --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.velocity.runtime", "RuntimeServices", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] + - ["org.apache.velocity.runtime", "RuntimeServices", True, "parse", "", "", "Argument[0]", "ssti", "manual"] + - ["org.apache.velocity.runtime", "RuntimeSingleton", True, "parse", "", "", "Argument[0]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml new file mode 100644 index 00000000000..4d3ce4c37ed --- /dev/null +++ b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.apache.velocity.runtime.resource.util", "StringResourceRepository", True, "putStringResource", "", "", "Argument[1]", "ssti", "manual"] diff --git a/java/ql/lib/ext/org.codehaus.groovy.control.model.yml b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml new file mode 100644 index 00000000000..77b03818172 --- /dev/null +++ b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.codehaus.groovy.control", "CompilationUnit", False, "compile", "", "", "Argument[-1]", "groovy", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.model.yml b/java/ql/lib/ext/org.dom4j.model.yml new file mode 100644 index 00000000000..b2e5c2ed379 --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.dom4j", "DocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "selectNodes", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentHelper", False, "sort", "", "", "Argument[1]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "matches", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "numberValueOf", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectNodes", "", "", "Argument[0..1]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectObject", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "selectSingleNode", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "Node", True, "valueOf", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.tree.model.yml b/java/ql/lib/ext/org.dom4j.tree.model.yml new file mode 100644 index 00000000000..0896937bb16 --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.tree.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.dom4j.tree", "AbstractNode", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.tree", "AbstractNode", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.util.model.yml b/java/ql/lib/ext/org.dom4j.util.model.yml new file mode 100644 index 00000000000..d7dc55cd145 --- /dev/null +++ b/java/ql/lib/ext/org.dom4j.util.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] diff --git a/java/ql/lib/ext/org.hibernate.model.yml b/java/ql/lib/ext/org.hibernate.model.yml new file mode 100644 index 00000000000..bfc232a82a1 --- /dev/null +++ b/java/ql/lib/ext/org.hibernate.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.hibernate", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "Session", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "Session", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.jboss.logging.model.yml b/java/ql/lib/ext/org.jboss.logging.model.yml new file mode 100644 index 00000000000..069ae852b77 --- /dev/null +++ b/java/ql/lib/ext/org.jboss.logging.model.yml @@ -0,0 +1,329 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.jdbi.v3.core.model.yml b/java/ql/lib/ext/org.jdbi.v3.core.model.yml new file mode 100644 index 00000000000..fd7f4e824ac --- /dev/null +++ b/java/ql/lib/ext/org.jdbi.v3.core.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.jooq.model.yml b/java/ql/lib/ext/org.jooq.model.yml new file mode 100644 index 00000000000..cf7fc22a923 --- /dev/null +++ b/java/ql/lib/ext/org.jooq.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.jooq", "PlainSQL", False, "", "", "Annotated", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.json.model.yml b/java/ql/lib/ext/org.json.model.yml new file mode 100644 index 00000000000..da97dfadb38 --- /dev/null +++ b/java/ql/lib/ext/org.json.model.yml @@ -0,0 +1,241 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.json", "CDL", False, "rowToJSONArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "rowToJSONObject", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "rowToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "toJSONArray", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "CDL", False, "toString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "escape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Cookie", False, "unescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CookieList", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "CookieList", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTP", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTP", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "HTTPTokener", False, "HTTPTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "HTTPTokener", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(JSONArray)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(JSONTokener)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(Object)", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "JSONArray", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "iterator", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONArray", False, "join", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "join", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "opt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigDecimal", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBigInteger", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optDouble", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optEnum", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optFloat", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optLong", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optNumber", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "optQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "optString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "put", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Map)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Map)", "", "Argument[1].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,float)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(int,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "put", "(long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Collection)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(JSONArray)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "putAll", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONArray", False, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "remove", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "toList", "", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONArray", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONArray", False, "write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONArray", False, "write", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONML", False, "toJSONArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONML", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONML", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONObject,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONObject,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(JSONTokener)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Map)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(Object,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "JSONObject", "(String,Locale)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "accumulate", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "accumulate", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "append", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "doubleToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", True, "entrySet", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getNames", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.json", "JSONObject", False, "getNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "getString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "increment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "increment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "keySet", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "keys", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.json", "JSONObject", False, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "numberToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "opt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigDecimal", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigDecimal", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optBigInteger", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBigInteger", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optBoolean", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optDouble", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optEnum", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optEnum", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optFloat", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optInt", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optJSONObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optLong", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optNumber", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optNumber", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "optQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "optString", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "put", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Collection)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Map)", "", "Argument[1].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,Object)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,boolean)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,double)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,double)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,float)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,float)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,long)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "put", "(String,long)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "putOnce", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "putOnce", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "putOpt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "putOpt", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.json", "JSONObject", False, "quote", "(String,Writer)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONObject", False, "remove", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "stringToValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toJSONArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toMap", "", "", "Argument[-1]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.json", "JSONObject", False, "toMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "valueToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "wrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONObject", False, "write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONObject", False, "write", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONPointer", False, "JSONPointer", "(List)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer", False, "JSONPointer", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer", False, "queryFrom", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer", False, "toURIFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONPointer$Builder", False, "append", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONPointer$Builder", False, "append", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONPointer$Builder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONString", True, "toJSONString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONStringer", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "JSONTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONTokener", True, "next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextClean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextTo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "nextValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "syntaxError", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONTokener", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "JSONWriter", True, "JSONWriter", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "array", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "endArray", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "endObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "key", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "key", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "object", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "value", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.json", "JSONWriter", True, "value", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "JSONWriter", True, "valueToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toJSONObject", "", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toJSONObject", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.json", "Property", False, "toProperties", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.json", "Property", False, "toProperties", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.json", "XML", False, "escape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "stringToValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "toJSONObject", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "toString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XML", False, "unescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "XMLTokener", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextCDATA", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextEntity", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextMeta", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLTokener", False, "nextToken", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.json", "XMLXsiTypeConverter", True, "convert", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.compiler.model.yml b/java/ql/lib/ext/org.mvel2.compiler.model.yml new file mode 100644 index 00000000000..0e7f68faea0 --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.compiler.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.mvel2.compiler", "Accessor", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "CompiledAccExpression", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "CompiledExpression", False, "getDirectValue", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.compiler", "ExecutableStatement", False, "getValue", "", "", "Argument[-1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.jsr223.model.yml b/java/ql/lib/ext/org.mvel2.jsr223.model.yml new file mode 100644 index 00000000000..eeb0cbc7984 --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.jsr223.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.mvel2.jsr223", "MvelCompiledScript", False, "eval", "", "", "Argument[-1]", "mvel", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "evaluate", "", "", "Argument[0]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.model.yml b/java/ql/lib/ext/org.mvel2.model.yml new file mode 100644 index 00000000000..fd7778c89a6 --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.mvel2", "MVEL", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "evalToBoolean", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "evalToString", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeAllExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "executeSetExpression", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2", "MVELRuntime", False, "execute", "", "", "Argument[1]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.templates.model.yml b/java/ql/lib/ext/org.mvel2.templates.model.yml new file mode 100644 index 00000000000..0e31cee38b0 --- /dev/null +++ b/java/ql/lib/ext/org.mvel2.templates.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.mvel2.templates", "TemplateRuntime", False, "eval", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.templates", "TemplateRuntime", False, "execute", "", "", "Argument[0]", "mvel", "manual"] diff --git a/java/ql/lib/ext/org.scijava.log.model.yml b/java/ql/lib/ext/org.scijava.log.model.yml new file mode 100644 index 00000000000..303dbae27e2 --- /dev/null +++ b/java/ql/lib/ext/org.scijava.log.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.scijava.log", "Logger", True, "alwaysLog", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.model.yml b/java/ql/lib/ext/org.slf4j.model.yml new file mode 100644 index 00000000000..6ff2f31847d --- /dev/null +++ b/java/ql/lib/ext/org.slf4j.model.yml @@ -0,0 +1,55 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.slf4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.spi.model.yml b/java/ql/lib/ext/org.slf4j.spi.model.yml new file mode 100644 index 00000000000..59e4d144157 --- /dev/null +++ b/java/ql/lib/ext/org.slf4j.spi.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addArgument", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addArgument", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addKeyValue", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addKeyValue", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "addMarker", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "setCause", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.beans.model.yml b/java/ql/lib/ext/org.springframework.beans.model.yml new file mode 100644 index 00000000000..d3579370ec9 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.beans.model.yml @@ -0,0 +1,35 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(List)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(Map)", "", "Argument[0].MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(Map)", "", "Argument[0].MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "MutablePropertyValues", "(PropertyValues)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "add", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(PropertyValue)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(PropertyValue)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValue", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[0].MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(Map)", "", "Argument[0].MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(PropertyValues)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "addPropertyValues", "(PropertyValues)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "get", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValueList", "", "", "Argument[-1].Element", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "getPropertyValues", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.beans", "MutablePropertyValues", True, "setPropertyValueAt", "", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue)", "", "Argument[0]", "Argument[-1]", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue,Object)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(PropertyValue,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "PropertyValue", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "getName", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValue", False, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValues", True, "getPropertyValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.beans", "PropertyValues", True, "getPropertyValues", "", "", "Argument[-1].Element", "ReturnValue.ArrayElement", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml new file mode 100644 index 00000000000..bd7c5d8c5c1 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.boot.jdbc", "DataSourceBuilder", False, "url", "(String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.cache.model.yml b/java/ql/lib/ext/org.springframework.cache.model.yml new file mode 100644 index 00000000000..6fd3cf4610d --- /dev/null +++ b/java/ql/lib/ext/org.springframework.cache.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.cache", "Cache", True, "get", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "get", "(Object,Callable)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "get", "(Object,Class)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "getNativeCache", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "getNativeCache", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "put", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "put", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache", True, "putIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueRetrievalException", False, "ValueRetrievalException", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueRetrievalException", False, "getKey", "", "", "Argument[-1].MapKey", "ReturnValue", "value", "manual"] + - ["org.springframework.cache", "Cache$ValueWrapper", True, "get", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.context.model.yml b/java/ql/lib/ext/org.springframework.context.model.yml new file mode 100644 index 00000000000..c4097103179 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.context.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],Locale)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],String,Locale)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.context", "MessageSource", True, "getMessage", "(String,Object[],String,Locale)", "", "Argument[2]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.data.repository.model.yml b/java/ql/lib/ext/org.springframework.data.repository.model.yml new file mode 100644 index 00000000000..82a5ba0ec10 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.data.repository.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.data.repository", "CrudRepository", True, "save", "", "", "Argument[0]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.http.model.yml b/java/ql/lib/ext/org.springframework.http.model.yml new file mode 100644 index 00000000000..2dac7192da2 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.http.model.yml @@ -0,0 +1,93 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(HttpMethod,URI)", "", "Argument[1]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(MultiValueMap,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI,Type)", "", "Argument[2]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI)", "", "Argument[3]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI,Type)", "", "Argument[3]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "get", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "head", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "method", "", "", "Argument[1]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "options", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "patch", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "post", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "HttpEntity", "(Object,MultiValueMap)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "getBody", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpEntity", True, "getHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "HttpHeaders", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "HttpHeaders", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "add", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(String,List)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "addAll", "(String,List)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "encodeBasicAuth", "(String,String,Charset)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "formatHeaders", "(MultiValueMap)", "", "Argument[0].MapKey", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "formatHeaders", "(MultiValueMap)", "", "Argument[0].MapValue.Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "get", "(Object)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlAllowHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlAllowOrigin", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlExposeHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getAccessControlRequestHeaders", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getCacheControl", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getConnection", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getETag", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getETagValuesAsList", "(String)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getFieldValues", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getFirst", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getHost", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getIfMatch", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getIfNoneMatch", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getLocation", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getOrEmpty", "(Object)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getOrigin", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getPragma", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getUpgrade", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getValuesAsList", "(String)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "getVary", "()", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.http", "HttpHeaders", True, "set", "(String,String)", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "RequestEntity", True, "getUrl", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatus)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "created", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "of", "(Optional)", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ok", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "body", "(Object)", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "contentLength", "(long)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$BodyBuilder", True, "contentType", "(MediaType)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "allow", "(HttpMethod[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "build", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "eTag", "(String)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "eTag", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "header", "(String,String[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(Consumer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(HttpHeaders)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "headers", "(HttpHeaders)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "lastModified", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "location", "(URI)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "location", "(URI)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity$HeadersBuilder", True, "varyBy", "(String[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.core.model.yml b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml new file mode 100644 index 00000000000..9374293d0bb --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "(String[])", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "execute", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "query", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForList", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForMap", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForObject", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForRowSet", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForStream", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "update", "", "", "Argument[0]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml new file mode 100644 index 00000000000..7bb84c37e2c --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.jdbc.datasource", "AbstractDriverBasedDataSource", False, "setUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.object.model.yml b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml new file mode 100644 index 00000000000..74e30d28068 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.jdbc.object", "BatchSqlUpdate", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQuery", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQueryWithParameters", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "RdbmsOperation", True, "setSql", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlCall", False, "SqlCall", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlFunction", False, "SqlFunction", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlQuery", False, "SqlQuery", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "SqlUpdate", False, "SqlUpdate", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "UpdatableSqlQuery", False, "UpdatableSqlQuery", "", "", "Argument[1]", "sql", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jndi.model.yml b/java/ql/lib/ext/org.springframework.jndi.model.yml new file mode 100644 index 00000000000..f0d5f7b692d --- /dev/null +++ b/java/ql/lib/ext/org.springframework.jndi.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.jndi", "JndiTemplate", False, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ldap.core.model.yml b/java/ql/lib/ext/org.springframework.ldap.core.model.yml new file mode 100644 index 00000000000..962dec40c59 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ldap.core.model.yml @@ -0,0 +1,38 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.ldap.core", "LdapOperations", True, "findByDn", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(Name,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookup", "(String,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "lookupContext", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(Name,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(LdapQuery,String)", "", "Argument[0]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "find", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "findOne", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "search", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForContext", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForObject", "", "", "Argument[0..1]", "ldap", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ldap.model.yml b/java/ql/lib/ext/org.springframework.ldap.model.yml new file mode 100644 index 00000000000..b42e3e85959 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ldap.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.ldap", "LdapOperations", True, "findByDn", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "list", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "listBindings", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "lookup", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "lookupContext", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "rename", "", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(Name,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,int,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "search", "(String,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "searchForObject", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] + - ["org.springframework.ldap", "LdapOperations", True, "searchForObject", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml b/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml new file mode 100644 index 00000000000..e8d9ab1bef5 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.security.web.savedrequest.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getHeaderNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getHeaderValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getParameterMap", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getParameterValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.security.web.savedrequest", "SavedRequest", True, "getRedirectUrl", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ui.model.yml b/java/ql/lib/ext/org.springframework.ui.model.yml new file mode 100644 index 00000000000..7e230d11f2f --- /dev/null +++ b/java/ql/lib/ext/org.springframework.ui.model.yml @@ -0,0 +1,37 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ConcurrentModel", False, "ConcurrentModel", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Collection)", "", "Argument[0].Element", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAllAttributes", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "addAttribute", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "asMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "asMap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "getAttribute", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "Model", True, "mergeAttributes", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "ModelMap", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Collection)", "", "Argument[0].Element", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAllAttributes", "(Map)", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(Object)", "", "Argument[0]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(String,Object)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "addAttribute", "(String,Object)", "", "Argument[1]", "Argument[-1].MapValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "getAttribute", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.ui", "ModelMap", False, "mergeAttributes", "", "", "Argument[0].MapValue", "Argument[-1].MapValue", "value", "manual"] diff --git a/java/ql/lib/ext/org.springframework.util.model.yml b/java/ql/lib/ext/org.springframework.util.model.yml new file mode 100644 index 00000000000..817f9b43c01 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.util.model.yml @@ -0,0 +1,144 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.util", "AntPathMatcher", False, "combine", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "doMatch", "", "", "Argument[1]", "Argument[3].MapValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "extractPathWithinPattern", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "extractUriTemplateVariables", "", "", "Argument[1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "tokenizePath", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "AntPathMatcher", False, "tokenizePattern", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "AutoPopulatingList", False, "AutoPopulatingList", "(java.util.List,java.lang.Class)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "AutoPopulatingList", False, "AutoPopulatingList", "(java.util.List,org.springframework.util.AutoPopulatingList.ElementFactory)", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeFromString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeFromUrlSafeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "decodeUrlSafe", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeToUrlSafeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "Base64Utils", False, "encodeUrlSafe", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "arrayToList", "", "", "Argument[0].ArrayElement", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "findFirstMatch", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "findValueOfType", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "firstElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "lastElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergeArrayIntoCollection", "", "", "Argument[0].ArrayElement", "Argument[1].Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergePropertiesIntoMap", "", "", "Argument[0].MapKey", "Argument[1].MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "mergePropertiesIntoMap", "", "", "Argument[0].MapValue", "Argument[1].MapValue", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toIterator", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toMultiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "toMultiValueMap", "", "", "Argument[0].MapValue.Element", "ReturnValue.MapValue.Element", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "unmodifiableMultiValueMap", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "CollectionUtils", False, "unmodifiableMultiValueMap", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "CompositeIterator", False, "add", "", "", "Argument[0].Element", "Argument[-1].Element", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getReference", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getReference", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getSegment", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "ConcurrentReferenceHashMap", False, "getSegment", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.util", "FastByteArrayOutputStream", False, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copyToByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copyToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "FileSystemUtils", False, "copyRecursively", "(java.io.File,java.io.File)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "LinkedMultiValueMap", "(java.util.Map)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "LinkedMultiValueMap", "(java.util.Map)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "deepCopy", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "LinkedMultiValueMap", False, "deepCopy", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "add", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "add", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(java.lang.Object,java.util.List)", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(java.lang.Object,java.util.List)", "", "Argument[1].Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(org.springframework.util.MultiValueMap)", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addAll", "(org.springframework.util.MultiValueMap)", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addIfAbsent", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "addIfAbsent", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "getFirst", "", "", "Argument[-1].MapValue.Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "set", "", "", "Argument[0]", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "set", "", "", "Argument[1]", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "setAll", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "setAll", "", "", "Argument[0].MapValue", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "toSingleValueMap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMap", True, "toSingleValueMap", "", "", "Argument[-1].MapValue.Element", "ReturnValue.MapValue", "value", "manual"] + - ["org.springframework.util", "MultiValueMapAdapter", False, "MultiValueMapAdapter", "", "", "Argument[0].MapKey", "Argument[-1].MapKey", "value", "manual"] + - ["org.springframework.util", "MultiValueMapAdapter", False, "MultiValueMapAdapter", "", "", "Argument[0].MapValue.Element", "Argument[-1].MapValue.Element", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "addObjectToArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "addObjectToArray", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "toObjectArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "ObjectUtils", False, "unwrapOptional", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "load", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "loadFromXml", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "store", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "store", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "storeToXml", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertiesPersister", True, "storeToXml", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "PropertyPlaceholderHelper", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "parseStringValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "replacePlaceholders", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "PropertyPlaceholderHelper", False, "replacePlaceholders", "(java.lang.String,java.util.Properties)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "extractArchiveURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "extractJarFileURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "getFile", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "getURL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "ResourceUtils", False, "toURI", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "combine", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "matchAndExtract", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "matchAndExtract", "", "", "Argument[1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "RouteMatcher", True, "parseRoute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SerializationUtils", False, "deserialize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SerializationUtils", False, "serialize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(byte[],java.io.OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(java.io.InputStream,java.io.OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copy", "(java.lang.String,java.nio.charset.Charset,java.io.OutputStream)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyRange", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyToByteArray", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StreamUtils", False, "copyToString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "addStringToArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "addStringToArray", "", "", "Argument[1]", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "applyRelativePath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToCommaDelimitedString", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToDelimitedString", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "arrayToDelimitedString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "capitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "cleanPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToCommaDelimitedString", "", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToDelimitedString", "", "", "Argument[0].Element", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "collectionToDelimitedString", "", "", "Argument[1..3]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "commaDelimitedListToSet", "", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "commaDelimitedListToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "concatenateStringArrays", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "delete", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "deleteAny", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "delimitedListToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "getFilename", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "getFilenameExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "mergeStringArrays", "", "", "Argument[0..1].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "quote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "quoteIfString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "removeDuplicateStrings", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "sortStringArray", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "split", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "splitArrayElementsIntoProperties", "", "", "Argument[0].ArrayElement", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "splitArrayElementsIntoProperties", "", "", "Argument[0].ArrayElement", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "stripFilenameExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "toStringArray", "", "", "Argument[0].Element", "ReturnValue.ArrayElement", "value", "manual"] + - ["org.springframework.util", "StringUtils", False, "tokenizeToStringArray", "", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimAllWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimArrayElements", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimLeadingCharacter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimLeadingWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimTrailingCharacter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimTrailingWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "trimWhitespace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "uncapitalize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "unqualify", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringUtils", False, "uriDecode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "StringValueResolver", False, "resolveStringValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.util", "SystemPropertyUtils", False, "resolvePlaceholders", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.validation.model.yml b/java/ql/lib/ext/org.springframework.validation.model.yml new file mode 100644 index 00000000000..190254ad2d1 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.validation.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.validation", "Errors", True, "addAllErrors", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getAllErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getFieldError", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getFieldErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getGlobalError", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "getGlobalErrors", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "reject", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "", "", "Argument[3]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "(java.lang.String,java.lang.String,java.lang.Object[],java.lang.String)", "", "Argument[2].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.validation", "Errors", True, "rejectValue", "(java.lang.String,java.lang.String,java.lang.String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.client.model.yml b/java/ql/lib/ext/org.springframework.web.client.model.yml new file mode 100644 index 00000000000..69f4cb64fc6 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.client.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.web.client", "RestTemplate", False, "delete", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "doExecute", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForLocation", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForObject", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "put", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.context.request.model.yml b/java/ql/lib/ext/org.springframework.web.context.request.model.yml new file mode 100644 index 00000000000..306bb87348e --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.context.request.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.springframework.web.context.request", "WebRequest", False, "getDescription", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeader", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeaderNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getHeaderValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameter", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterMap", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.context.request", "WebRequest", False, "getParameterValues", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.multipart.model.yml b/java/ql/lib/ext/org.springframework.web.multipart.model.yml new file mode 100644 index 00000000000..7c0505cbcc4 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.multipart.model.yml @@ -0,0 +1,34 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.springframework.web.multipart", "MultipartFile", True, "getBytes", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getContentType", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getOriginalFilename", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getResource", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFile", "(String)", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileMap", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileNames", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFiles", "(String)", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultiFileMap", "()", "", "ReturnValue", "remote", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultipartContentType", "(String)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.web.multipart", "MultipartFile", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getOriginalFilename", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartFile", True, "getResource", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartHttpServletRequest", True, "getMultipartHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartHttpServletRequest", True, "getRequestHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFileNames", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getFiles", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartRequest", True, "getMultiFileMap", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.multipart", "MultipartResolver", True, "resolveMultipart", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml new file mode 100644 index 00000000000..cb2d1db4444 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.web.reactive.function.client", "WebClient", False, "create", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.reactive.function.client", "WebClient$Builder", False, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.util.model.yml b/java/ql/lib/ext/org.springframework.web.util.model.yml new file mode 100644 index 00000000000..336d22b8696 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.web.util.model.yml @@ -0,0 +1,169 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "getBaseUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setBaseUrl", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "AbstractUriTemplateHandler", True, "setDefaultUriVariables", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + # Writing to a `Request` or `Response` currently doesn't propagate taint to the object itself. + - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "ContentCachingRequestWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingRequestWrapper", False, "getContentAsByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "ContentCachingResponseWrapper", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "getContentAsByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ContentCachingResponseWrapper", False, "getContentInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "DefaultUriBuilderFactory", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "builder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "getDefaultUriVariables", "", "", "Argument[-1]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "setDefaultUriVariables", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "DefaultUriBuilderFactory", False, "uriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscapeDecimal", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlEscapeHex", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "HtmlUtils", False, "htmlUnescape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletContextPropertyUtils", False, "resolvePlaceholders", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getCachedPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getCachedPathValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "getParsedRequestPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "parseAndCache", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "ServletRequestPathUtils", False, "setParsedRequestPath", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Map)", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "build", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "fragment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "fragment", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "host", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "host", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "path", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "path", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "pathSegment", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "pathSegment", "", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "port", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "port", "(java.lang.String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "query", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "query", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParamIfPresent", "", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "queryParams", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replacePath", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replacePath", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQuery", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQuery", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "(String,Collection)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[0].MapKey", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "replaceQueryParams", "", "", "Argument[0].MapValue.Element", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "scheme", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "scheme", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "userInfo", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriBuilder", True, "userInfo", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilderFactory", True, "builder", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriBuilderFactory", True, "uriString", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "UriComponents", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "copyToUriComponentsBuilder", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "encode", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "expand", "(UriTemplateVariables)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getFragment", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getHost", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getPathSegments", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQueryParams", "", "", "Argument[-1]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getQueryParams", "", "", "Argument[-1]", "ReturnValue.MapValue.Element", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getScheme", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getSchemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "getUserInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "normalize", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents", False, "toUriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponents$UriTemplateVariables", True, "getValue", "", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "build", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "buildAndExpand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "buildAndExpand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "cloneBuilder", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "encode", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromHttpRequest", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromHttpUrl", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromOriginHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "fromUriString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "parseForwardedFor", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "schemeSpecificPart", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "schemeSpecificPart", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "toUriString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uri", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uri", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriComponents", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriVariables", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "UriComponentsBuilder", False, "uriVariables", "", "", "Argument[0].MapValue", "Argument[-1]", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "expand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "expand", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "getVariableNames", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "match", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplate", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "", "", "Argument[-1..0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "(String,Map)", "", "Argument[1].MapValue", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriTemplateHandler", True, "expand", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeAuthority", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeFragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePathSegment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodePort", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParam", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParams", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeQueryParams", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeScheme", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Map)", "", "Argument[0].MapKey", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Map)", "", "Argument[0].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUriVariables", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "encodeUserInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UriUtils", False, "extractFileExtension", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeMatrixVariables", "", "", "Argument[1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeMatrixVariables", "", "", "Argument[1].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodePathVariables", "", "", "Argument[1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodePathVariables", "", "", "Argument[1].MapValue", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "decodeRequestString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getContextPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingContextPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingQueryString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getOriginatingRequestUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getPathWithinApplication", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getPathWithinServletMapping", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getRequestUri", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getResolvedLookupPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "getServletPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "removeSemicolonContent", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "UrlPathHelper", False, "resolveAndCacheLookupPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "findParameterValue", "(Map,String)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "findParameterValue", "(ServletRequest,String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getCookie", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getNativeRequest", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getNativeResponse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getParametersStartingWith", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getParametersStartingWith", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getRealPath", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getRequiredSessionAttribute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "getSessionAttribute", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "parseMatrixVariables", "", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "parseMatrixVariables", "", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["org.springframework.web.util", "WebUtils", False, "setSessionAttribute", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.thymeleaf.model.yml b/java/ql/lib/ext/org.thymeleaf.model.yml new file mode 100644 index 00000000000..fb294acafe6 --- /dev/null +++ b/java/ql/lib/ext/org.thymeleaf.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.thymeleaf", "ITemplateEngine", True, "process", "", "", "Argument[0]", "ssti", "manual"] + - ["org.thymeleaf", "ITemplateEngine", True, "processThrottled", "", "", "Argument[0]", "ssti", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.thymeleaf", "TemplateSpec", False, "TemplateSpec", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["org.thymeleaf", "TemplateSpec", False, "getTemplate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/org.xml.sax.model.yml b/java/ql/lib/ext/org.xml.sax.model.yml new file mode 100644 index 00000000000..71f1194a94e --- /dev/null +++ b/java/ql/lib/ext/org.xml.sax.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.xml.sax", "InputSource", False, "InputSource", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/org.xmlpull.v1.model.yml b/java/ql/lib/ext/org.xmlpull.v1.model.yml new file mode 100644 index 00000000000..9002fda11c1 --- /dev/null +++ b/java/ql/lib/ext/org.xmlpull.v1.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.xmlpull.v1", "XmlPullParser", False, "getName", "()", "", "ReturnValue", "remote", "manual"] + - ["org.xmlpull.v1", "XmlPullParser", False, "getNamespace", "()", "", "ReturnValue", "remote", "manual"] + - ["org.xmlpull.v1", "XmlPullParser", False, "getText", "()", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/play.mvc.model.yml b/java/ql/lib/ext/play.mvc.model.yml new file mode 100644 index 00000000000..a1f8dc60fe0 --- /dev/null +++ b/java/ql/lib/ext/play.mvc.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["play.mvc", "Http$RequestHeader", False, "getHeader", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "getQueryString", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "header", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", False, "queryString", "", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.form.model.yml b/java/ql/lib/ext/ratpack.core.form.model.yml new file mode 100644 index 00000000000..f3df142cf9d --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.form.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.core.form", "Form", True, "file", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.form", "Form", True, "files", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.form", "UploadedFile", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.handling.model.yml b/java/ql/lib/ext/ratpack.core.handling.model.yml new file mode 100644 index 00000000000..0882d1b983d --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.handling.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + # All Context#parse methods that return a Promise are remote flow sources. + - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(java.lang.Class,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["ratpack.core.handling", "Context", True, "parse", "(ratpack.http.TypedData,ratpack.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.core.http.model.yml b/java/ql/lib/ext/ratpack.core.http.model.yml new file mode 100644 index 00000000000..2f6bc7fa17c --- /dev/null +++ b/java/ql/lib/ext/ratpack.core.http.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["ratpack.core.http", "Request", True, "getBody", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getContentLength", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getPath", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getQuery", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getQueryParams", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getRawUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "getUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.core.http", "Request", True, "oneCookie", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.core.http", "Headers", True, "asMultiValueMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "Headers", True, "getNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getContentType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.core.http", "TypedData", True, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.exec.model.yml b/java/ql/lib/ext/ratpack.exec.model.yml new file mode 100644 index 00000000000..b2c0b2a2922 --- /dev/null +++ b/java/ql/lib/ext/ratpack.exec.model.yml @@ -0,0 +1,53 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.exec", "Promise", True, "apply", "", "", "Argument[-1].Element", "Argument[0].Parameter[0].Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "apply", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingMap", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "blockingOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "cacheIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatLeft", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMap", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatMapError", "", "", "Argument[1].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatRight", "(Function)", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "flatten", "", "", "Argument[0].ReturnValue.Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "left", "(Promise)", "", "Argument[0].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "map", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapError", "", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[-1].Element", "Argument[2].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "mapIf", "", "", "Argument[2].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "next", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOp", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOpIf", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "nextOpIf", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "replace", "", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "", "", "Argument[-1].Element", "ReturnValue.Element.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "right", "(Promise)", "", "Argument[0].Element", "ReturnValue.Element.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "route", "", "", "Argument[-1].Element", "Argument[1].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "sync", "", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "then", "", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.exec", "Promise", True, "value", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["ratpack.exec", "Promise", True, "wiretap", "", "", "Argument[-1].Element", "Argument[0].Parameter[0].Element", "value", "manual"] + - ["ratpack.exec", "Result", True, "getValue", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Result", True, "getValueOrThrow", "", "", "Argument[-1].Element", "ReturnValue", "value", "manual"] + - ["ratpack.exec", "Result", True, "success", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/lib/ext/ratpack.form.model.yml b/java/ql/lib/ext/ratpack.form.model.yml new file mode 100644 index 00000000000..3c4f6b2dd2b --- /dev/null +++ b/java/ql/lib/ext/ratpack.form.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.form", "Form", True, "file", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.form", "Form", True, "files", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.form", "UploadedFile", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.func.model.yml b/java/ql/lib/ext/ratpack.func.model.yml new file mode 100644 index 00000000000..6cd78dc39d9 --- /dev/null +++ b/java/ql/lib/ext/ratpack.func.model.yml @@ -0,0 +1,44 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.func", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["ratpack.func", "MultiValueMap", True, "getAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.func", "Pair", True, "getLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "getRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + # `map` maps over the `Pair` + - ["ratpack.func", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + # `mapLeft` & `mapRight` map over their respective fields + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.func", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + # `nestLeft` Pair.nestLeft(C) -> Pair, B> + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + # `nestRight` Pair.nestRight(C) -> Pair> + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "of", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "of", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pair", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pair", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushLeft", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushRight", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "pushRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "()", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.func", "Pair", True, "right", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] diff --git a/java/ql/lib/ext/ratpack.handling.model.yml b/java/ql/lib/ext/ratpack.handling.model.yml new file mode 100644 index 00000000000..1552fc7c1fd --- /dev/null +++ b/java/ql/lib/ext/ratpack.handling.model.yml @@ -0,0 +1,20 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + # All Context#parse methods that return a Promise are remote flow sources. + - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(com.google.common.reflect.TypeToken,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(java.lang.Class)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(java.lang.Class,java.lang.Object)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.parse.Parse)", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapKey", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.core.http.TypedData,ratpack.core.parse.Parse)", "", "Argument[0]", "ReturnValue.MapValue", "taint", "manual"] + - ["ratpack.handling", "Context", True, "parse", "(ratpack.http.TypedData,ratpack.parse.Parse)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.http.model.yml b/java/ql/lib/ext/ratpack.http.model.yml new file mode 100644 index 00000000000..340d3d29905 --- /dev/null +++ b/java/ql/lib/ext/ratpack.http.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["ratpack.http", "Request", True, "getBody", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getContentLength", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getCookies", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getPath", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getQuery", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getQueryParams", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getRawUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "getUri", "", "", "ReturnValue", "remote", "manual"] + - ["ratpack.http", "Request", True, "oneCookie", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.http", "Headers", True, "asMultiValueMap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "Headers", True, "getNames", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getContentType", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getInputStream", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "getText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["ratpack.http", "TypedData", True, "writeTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/java/ql/lib/ext/ratpack.util.model.yml b/java/ql/lib/ext/ratpack.util.model.yml new file mode 100644 index 00000000000..0510897c4c6 --- /dev/null +++ b/java/ql/lib/ext/ratpack.util.model.yml @@ -0,0 +1,44 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["ratpack.util", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "asMultimap", "", "", "Argument[-1].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "", "", "Argument[-1].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "()", "", "Argument[-1].MapValue", "ReturnValue.MapValue.Element", "value", "manual"] + - ["ratpack.util", "MultiValueMap", True, "getAll", "(Object)", "", "Argument[-1].MapValue", "ReturnValue.Element", "value", "manual"] + - ["ratpack.util", "Pair", True, "getLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "getRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "()", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "left", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + # `map` maps over the `Pair` + - ["ratpack.util", "Pair", True, "map", "", "", "Argument[-1]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "map", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + # `mapLeft` & `mapRight` map over their respective fields + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapLeft", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[-1].Field[ratpack.func.Pair.right]", "Argument[0].Parameter[0]", "value", "manual"] + - ["ratpack.util", "Pair", True, "mapRight", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + # `nestLeft` Pair.nestLeft(C) -> Pair, B> + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left].Field[ratpack.func.Pair.left]", "value", "manual"] + # `nestRight` Pair.nestRight(C) -> Pair> + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "nestRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right].Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "of", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "of", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pair", "", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pair", "", "", "Argument[1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushLeft", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushLeft", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushRight", "(Object)", "", "Argument[-1]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "pushRight", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "()", "", "Argument[-1].Field[ratpack.func.Pair.right]", "ReturnValue", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "(Object)", "", "Argument[-1].Field[ratpack.func.Pair.left]", "ReturnValue.Field[ratpack.func.Pair.left]", "value", "manual"] + - ["ratpack.util", "Pair", True, "right", "(Object)", "", "Argument[0]", "ReturnValue.Field[ratpack.func.Pair.right]", "value", "manual"] diff --git a/java/ql/lib/ext/retrofit2.model.yml b/java/ql/lib/ext/retrofit2.model.yml new file mode 100644 index 00000000000..51c4c0eed83 --- /dev/null +++ b/java/ql/lib/ext/retrofit2.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["retrofit2", "Retrofit$Builder", True, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 0d8258e5ef1..3219ed8b7dc 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,7 +1,15 @@ name: codeql/java-all -version: 0.4.4-dev +version: 0.5.0-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java library: true upgrades: upgrades +dependencies: + codeql/regex: ${workspace} + codeql/typetracking: ${workspace} + codeql/util: ${workspace} +dataExtensions: + - ext/*.model.yml + - ext/generated/*.model.yml + - ext/experimental/*.model.yml diff --git a/java/ql/lib/semmle/code/java/Annotation.qll b/java/ql/lib/semmle/code/java/Annotation.qll index 28f994053a2..fa010ec88c0 100644 --- a/java/ql/lib/semmle/code/java/Annotation.qll +++ b/java/ql/lib/semmle/code/java/Annotation.qll @@ -37,7 +37,9 @@ class Annotation extends @annotation, Expr { } /** Gets the annotation type declaration for this annotation. */ - override AnnotationType getType() { result = Expr.super.getType() } + override AnnotationType getType() { + result = Expr.super.getType().(Interface).getSourceDeclaration() + } /** Gets the annotation element with the specified `name`. */ AnnotationElement getAnnotationElement(string name) { @@ -249,7 +251,7 @@ private predicate filteredAnnotValue(Annotation a, Method m, Expr val) { private predicate sourceAnnotValue(Annotation a, Method m, Expr val) { annotValue(a, m, val) and - val.getFile().getExtension() = "java" + val.getFile().isSourceFile() } /** An abstract representation of language elements that can be annotated. */ diff --git a/java/ql/lib/semmle/code/java/Compilation.qll b/java/ql/lib/semmle/code/java/Compilation.qll index f38dc8ddb6b..c4b846edade 100644 --- a/java/ql/lib/semmle/code/java/Compilation.qll +++ b/java/ql/lib/semmle/code/java/Compilation.qll @@ -143,4 +143,9 @@ class Compilation extends @compilation { * Holds if the extractor encountered non-recoverable errors. */ predicate nonRecoverableErrors() { compilation_finished(this, _, _, 2) } + + /** + * Gets the piece of compilation information with the given key, if any. + */ + string getInfo(string key) { compilation_info(this, key, result) } } diff --git a/java/ql/lib/semmle/code/java/DependencyCounts.qll b/java/ql/lib/semmle/code/java/DependencyCounts.qll index 1010be48055..b34e774f1e1 100644 --- a/java/ql/lib/semmle/code/java/DependencyCounts.qll +++ b/java/ql/lib/semmle/code/java/DependencyCounts.qll @@ -91,7 +91,7 @@ predicate numDepends(RefType t, RefType dep, int value) { elem = a and usesType(a.getType(), dep) or elem = [a.getValue(_), a.getAnArrayValue(_)] and - elem.getFile().getExtension() = "java" and + elem.getFile().isSourceFile() and usesType(elem.(Expr).getType(), dep) ) or diff --git a/java/ql/lib/semmle/code/java/Diagnostics.qll b/java/ql/lib/semmle/code/java/Diagnostics.qll index 086998691bd..e6e16b4e07c 100644 --- a/java/ql/lib/semmle/code/java/Diagnostics.qll +++ b/java/ql/lib/semmle/code/java/Diagnostics.qll @@ -15,8 +15,18 @@ class Diagnostic extends @diagnostic { string getGeneratedBy() { diagnostics(this, result, _, _, _, _, _) } /** - * Gets the severity of the message, on a range from 1 to 5: 1=remark, - * 2=warning, 3=discretionary error, 4=error, 5=catastrophic error. + * Gets the severity of the message. + * + * For Java, this ranges from 1 to 8: + * 1=warning(low) + * 2=warning(normal) + * 3=warning(high) + * 4=error(low) Minor extractor errors, with minimal impact on analysis + * 5=error(normal) Most extractor errors, with local impact on analysis + * 6=error(high) Errors from the frontend + * 7=error(severe) Severe extractor errors affecting a single source file + * 8=error(global) Severe extractor errors likely to affect multiple source files + * For Kotlin, only the "normal" warning and error severities are used. */ int getSeverity() { diagnostics(this, _, result, _, _, _, _) } diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index 751fe1a1d64..08689f05f94 100644 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -71,6 +71,8 @@ class Element extends @element, Top { i = 11 and result = "Forwarder for a Kotlin class inheriting an interface default method" or i = 12 and result = "Argument for enum constructor call" + or + i = 13 and result = "The class around a local function, a lambda, or a function reference" ) } } diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index fedcfc8ecbb..a10da9ecc9f 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -1896,7 +1896,8 @@ class VarAccess extends Expr, @varaccess { class ExtensionReceiverAccess extends VarAccess { ExtensionReceiverAccess() { exists(Parameter p | - this.getVariable() = p and p.getPosition() = 0 and p.getCallable() instanceof ExtensionMethod + this.getVariable() = p and + p.isExtensionParameter() ) } diff --git a/java/ql/lib/semmle/code/java/Member.qll b/java/ql/lib/semmle/code/java/Member.qll index 102006b3213..62f9a22401d 100644 --- a/java/ql/lib/semmle/code/java/Member.qll +++ b/java/ql/lib/semmle/code/java/Member.qll @@ -327,18 +327,8 @@ class Callable extends StmtParent, Member, @callable { this instanceof Method and result instanceof Method and this.getName() + "$default" = result.getName() and - extraLeadingParams <= 1 and - ( - if ktExtensionFunctions(this, _, _) - then - // Both extension receivers are expected to occur at arg0, with any - // dispatch receiver inserted afterwards in the $default proxy's parameter list. - // Check the extension receiver matches here, and note regular args - // are bumped one position to the right. - regularParamsStartIdx = extraLeadingParams + 1 and - this.getParameterType(0).getErasure() = eraseRaw(result.getParameterType(0)) - else regularParamsStartIdx = extraLeadingParams - ) and + extraLeadingParams <= 1 and // 0 for static methods, 1 for instance methods + regularParamsStartIdx = extraLeadingParams and lastParamType instanceof TypeObject ) | @@ -638,6 +628,9 @@ class Constructor extends Callable, @constructor { /** Holds if this is a default constructor, not explicitly declared in source code. */ predicate isDefaultConstructor() { isDefConstr(this) } + /** Holds if this is a constructor without parameters. */ + predicate isParameterless() { this.getNumberOfParameters() = 0 } + override Constructor getSourceDeclaration() { constrs(this, _, _, _, _, result) } override string getSignature() { constrs(this, _, result, _, _, _) } @@ -824,4 +817,19 @@ class ExtensionMethod extends Method { KotlinType getExtendedKotlinType() { result = extendedKotlinType } override string getAPrimaryQlClass() { result = "ExtensionMethod" } + + /** + * Gets the index of the parameter that is the extension receiver. This is typically index 0. In case of `$default` + * extension methods that are defined as members, the index is 1. Index 0 is the dispatch receiver of the `$default` + * method. + */ + int getExtensionReceiverParameterIndex() { + if + exists(Method src | + this = src.getKotlinParameterDefaultsProxy() and + src.getNumberOfParameters() = this.getNumberOfParameters() - 3 // 2 extra parameters + 1 dispatch receiver + ) + then result = 1 + else result = 0 + } } diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index 4fe7e3f1ec5..0e52be33149 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -7,7 +7,7 @@ */ import java -import semmle.code.java.regex.RegexTreeView +import semmle.code.java.regex.RegexTreeView as RegexTreeView private newtype TPrintAstConfiguration = MkPrintAstConfiguration() @@ -120,7 +120,12 @@ private newtype TPrintAstNode = shouldPrint(lvde, _) and lvde.getParent() instanceof SingleLocalVarDeclParent } or TAnnotationsNode(Annotatable ann) { - shouldPrint(ann, _) and ann.hasDeclaredAnnotation() and not partOfAnnotation(ann) + shouldPrint(ann, _) and + ann.hasDeclaredAnnotation() and + not partOfAnnotation(ann) and + // The Kotlin compiler might add annotations that are only present in byte code, although the annotatable element is + // present in source code. + exists(Annotation a | a.getAnnotatedElement() = ann and shouldPrint(a, _)) } or TParametersNode(Callable c) { shouldPrint(c, _) and not c.hasNoParameters() } or TBaseTypesNode(ClassOrInterface ty) { shouldPrint(ty, _) } or @@ -134,8 +139,10 @@ private newtype TPrintAstNode = TImportsNode(CompilationUnit cu) { shouldPrint(cu, _) and exists(Import i | i.getCompilationUnit() = cu) } or - TRegExpTermNode(RegExpTerm term) { - exists(StringLiteral str | term.getRootTerm() = getParsedRegExp(str) and shouldPrint(str, _)) + TRegExpTermNode(RegexTreeView::RegExpTerm term) { + exists(StringLiteral str | + term.getRootTerm() = RegexTreeView::getParsedRegExp(str) and shouldPrint(str, _) + ) } /** @@ -291,19 +298,21 @@ final class AnnotationPartNode extends ExprStmtNode { override ElementNode getChild(int childIndex) { result.getElement() = - rank[childIndex](Element ch, string file, int line, int column | - ch = this.getAnAnnotationChild() and locationSortKeys(ch, file, line, column) + rank[childIndex](Element ch, string file, int line, int column, int idx | + ch = this.getAnnotationChild(idx) and locationSortKeys(ch, file, line, column) | - ch order by file, line, column + ch order by file, line, column, idx ) } - private Expr getAnAnnotationChild() { - result = element.(Annotation).getValue(_) + private Expr getAnnotationChild(int index) { + result = element.(Annotation).getValue(_) and + index >= 0 and + if exists(int x | x >= 0 | result.isNthChildOf(element, x)) + then result.isNthChildOf(element, index) + else result.isNthChildOf(element, -(index + 1)) or - result = element.(ArrayInit).getAnInit() - or - result = element.(ArrayInit).(Annotatable).getAnAnnotation() + result = element.(ArrayInit).getInit(index) } } @@ -316,7 +325,7 @@ final class StringLiteralNode extends ExprStmtNode { override PrintAstNode getChild(int childIndex) { childIndex = 0 and - result.(RegExpTermNode).getTerm() = getParsedRegExp(element) + result.(RegExpTermNode).getTerm() = RegexTreeView::getParsedRegExp(element) } } @@ -324,12 +333,12 @@ final class StringLiteralNode extends ExprStmtNode { * A node representing a regular expression term. */ class RegExpTermNode extends TRegExpTermNode, PrintAstNode { - RegExpTerm term; + RegexTreeView::RegExpTerm term; RegExpTermNode() { this = TRegExpTermNode(term) } /** Gets the `RegExpTerm` for this node. */ - RegExpTerm getTerm() { result = term } + RegexTreeView::RegExpTerm getTerm() { result = term } override PrintAstNode getChild(int childIndex) { result.(RegExpTermNode).getTerm() = term.getChild(childIndex) @@ -391,12 +400,6 @@ final class LocalTypeDeclStmtNode extends ExprStmtNode { } } -/** - * DEPRECATED: Renamed `LocalTypeDeclStmtNode` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ -deprecated class LocalClassDeclStmtNode = LocalTypeDeclStmtNode; - /** * A node representing a `ForStmt`. */ @@ -676,10 +679,10 @@ final class AnnotationsNode extends PrintAstNode, TAnnotationsNode { override ElementNode getChild(int childIndex) { result.getElement() = - rank[childIndex](Element e, string file, int line, int column | - e = ann.getAnAnnotation() and locationSortKeys(e, file, line, column) + rank[childIndex](Element e, string file, int line, int column, string s | + e = ann.getAnAnnotation() and locationSortKeys(e, file, line, column) and s = e.toString() | - e order by file, line, column + e order by file, line, column, s ) } diff --git a/java/ql/lib/semmle/code/java/Statement.qll b/java/ql/lib/semmle/code/java/Statement.qll index 2c8cff3c217..fe0ba23093a 100644 --- a/java/ql/lib/semmle/code/java/Statement.qll +++ b/java/ql/lib/semmle/code/java/Statement.qll @@ -781,12 +781,6 @@ class LocalTypeDeclStmt extends Stmt, @localtypedeclstmt { /** Gets the local type declared by this statement. */ LocalClassOrInterface getLocalType() { isLocalClassOrInterface(result, this) } - /** - * DEPRECATED: Renamed `getLocalType` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ - deprecated LocalClassOrInterface getLocalClass() { result = this.getLocalType() } - private string getDeclKeyword() { result = "class" and this.getLocalType() instanceof Class or @@ -802,12 +796,6 @@ class LocalTypeDeclStmt extends Stmt, @localtypedeclstmt { override string getAPrimaryQlClass() { result = "LocalTypeDeclStmt" } } -/** - * DEPRECATED: Renamed `LocalTypeDeclStmt` to reflect the fact that - * as of Java 16 interfaces can also be declared locally, not just classes. - */ -deprecated class LocalClassDeclStmt = LocalTypeDeclStmt; - /** An explicit `this(...)` constructor invocation. */ class ThisConstructorInvocationStmt extends Stmt, ConstructorCall, @constructorinvocationstmt { /** Gets an argument of this constructor invocation. */ diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index 63df6feef42..eff61ed0fde 100644 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -828,12 +828,6 @@ class LocalClassOrInterface extends NestedType, ClassOrInterface { /** Gets the statement that declares this local class. */ LocalTypeDeclStmt getLocalTypeDeclStmt() { isLocalClassOrInterface(this, result) } - /** - * DEPRECATED: renamed `getLocalTypeDeclStmt` to reflect the fact that - * as of Java 16 interfaces can also be declared locally. - */ - deprecated LocalTypeDeclStmt getLocalClassDeclStmt() { result = this.getLocalTypeDeclStmt() } - override string getAPrimaryQlClass() { result = "LocalClassOrInterface" } } diff --git a/java/ql/lib/semmle/code/java/Variable.qll b/java/ql/lib/semmle/code/java/Variable.qll index 7be49acf546..82314824395 100644 --- a/java/ql/lib/semmle/code/java/Variable.qll +++ b/java/ql/lib/semmle/code/java/Variable.qll @@ -91,7 +91,7 @@ class Parameter extends Element, @param, LocalScopeVariable { /** Holds if this formal parameter is a parameter representing the dispatch receiver in an extension method. */ predicate isExtensionParameter() { - this.getPosition() = 0 and this.getCallable() instanceof ExtensionMethod + this.getPosition() = this.getCallable().(ExtensionMethod).getExtensionReceiverParameterIndex() } /** diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 8460c662d5c..02e0953bbc5 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -1,22 +1,23 @@ /** * INTERNAL use only. This is an experimental API subject to change without notice. * - * Provides classes and predicates for dealing with flow models specified in CSV format. + * Provides classes and predicates for dealing with flow models specified + * in data extensions and CSV format. * * The CSV specification has the following columns: * - Sources: - * `namespace; type; subtypes; name; signature; ext; output; kind; provenance` + * `package; type; subtypes; name; signature; ext; output; kind; provenance` * - Sinks: - * `namespace; type; subtypes; name; signature; ext; input; kind; provenance` + * `package; type; subtypes; name; signature; ext; input; kind; provenance` * - Summaries: - * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance` - * - Negative Summaries: - * `namespace; type; name; signature; provenance` - * A negative summary is used to indicate that there is no flow via a callable. + * `package; type; subtypes; name; signature; ext; input; output; kind; provenance` + * - Neutrals: + * `package; type; name; signature; provenance` + * A neutral is used to indicate that there is no flow via a callable. * * The interpretation of a row is similar to API-graphs with a left-to-right * reading. - * 1. The `namespace` column selects a package. + * 1. The `package` column selects a package. * 2. The `type` column selects a type within that package. * 3. The `subtypes` is a boolean that indicates whether to jump to an * arbitrary subtype of that type. @@ -77,367 +78,109 @@ private import internal.DataFlowPrivate private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific private import internal.AccessPathSyntax +private import ExternalFlowExtensions as Extensions private import FlowSummary /** - * A module importing the frameworks that provide external flow data, - * ensuring that they are visible to the taint tracking / data flow library. - */ -private module Frameworks { - private import internal.ContainerFlow - private import semmle.code.java.frameworks.android.Android - private import semmle.code.java.frameworks.android.ContentProviders - private import semmle.code.java.frameworks.android.ExternalStorage - private import semmle.code.java.frameworks.android.Intent - private import semmle.code.java.frameworks.android.Notifications - private import semmle.code.java.frameworks.android.SharedPreferences - private import semmle.code.java.frameworks.android.Slice - private import semmle.code.java.frameworks.android.SQLite - private import semmle.code.java.frameworks.android.Widget - private import semmle.code.java.frameworks.android.XssSinks - private import semmle.code.java.frameworks.ApacheHttp - private import semmle.code.java.frameworks.apache.Collections - private import semmle.code.java.frameworks.apache.IO - private import semmle.code.java.frameworks.apache.Lang - private import semmle.code.java.frameworks.Flexjson - private import semmle.code.java.frameworks.generated - private import semmle.code.java.frameworks.guava.Guava - private import semmle.code.java.frameworks.jackson.JacksonSerializability - private import semmle.code.java.frameworks.javaee.jsf.JSFRenderer - private import semmle.code.java.frameworks.JavaIo - private import semmle.code.java.frameworks.JavaxJson - private import semmle.code.java.frameworks.JaxWS - private import semmle.code.java.frameworks.JoddJson - private import semmle.code.java.frameworks.JsonJava - private import semmle.code.java.frameworks.Logging - private import semmle.code.java.frameworks.Objects - private import semmle.code.java.frameworks.OkHttp - private import semmle.code.java.frameworks.Optional - private import semmle.code.java.frameworks.Regex - private import semmle.code.java.frameworks.Retrofit - private import semmle.code.java.frameworks.Stream - private import semmle.code.java.frameworks.Strings - private import semmle.code.java.frameworks.Thymeleaf - private import semmle.code.java.frameworks.ratpack.Ratpack - private import semmle.code.java.frameworks.ratpack.RatpackExec - private import semmle.code.java.frameworks.spring.SpringCache - private import semmle.code.java.frameworks.spring.SpringContext - private import semmle.code.java.frameworks.spring.SpringData - private import semmle.code.java.frameworks.spring.SpringHttp - private import semmle.code.java.frameworks.spring.SpringUtil - private import semmle.code.java.frameworks.spring.SpringUi - private import semmle.code.java.frameworks.spring.SpringValidation - private import semmle.code.java.frameworks.spring.SpringWebClient - private import semmle.code.java.frameworks.spring.SpringBeans - private import semmle.code.java.frameworks.spring.SpringWebMultipart - private import semmle.code.java.frameworks.spring.SpringWebUtil - private import semmle.code.java.security.AndroidIntentRedirection - private import semmle.code.java.security.ResponseSplitting - private import semmle.code.java.security.InformationLeak - private import semmle.code.java.security.Files - private import semmle.code.java.security.GroovyInjection - private import semmle.code.java.security.ImplicitPendingIntents - private import semmle.code.java.security.JexlInjectionSinkModels - private import semmle.code.java.security.JndiInjection - private import semmle.code.java.security.LdapInjection - private import semmle.code.java.security.MvelInjection - private import semmle.code.java.security.OgnlInjection - private import semmle.code.java.security.TemplateInjection - private import semmle.code.java.security.XPath - private import semmle.code.java.security.XsltInjection - private import semmle.code.java.frameworks.Jdbc - private import semmle.code.java.frameworks.Jdbi - private import semmle.code.java.frameworks.HikariCP - private import semmle.code.java.frameworks.SpringJdbc - private import semmle.code.java.frameworks.MyBatis - private import semmle.code.java.frameworks.Hibernate - private import semmle.code.java.frameworks.jOOQ - private import semmle.code.java.frameworks.JMS - private import semmle.code.java.frameworks.RabbitMQ - private import semmle.code.java.regex.RegexFlowModels - private import semmle.code.java.frameworks.kotlin.StdLib -} - -/** + * DEPRECATED: Define source models as data extensions instead. + * * A unit class for adding additional source model rows. * * Extend this class to add additional source definitions. */ -class SourceModelCsv extends Unit { +deprecated class SourceModelCsv = SourceModelCsvInternal; + +private class SourceModelCsvInternal extends Unit { /** Holds if `row` specifies a source definition. */ abstract predicate row(string row); } /** + * DEPRECATED: Define sink models as data extensions instead. + * * A unit class for adding additional sink model rows. * * Extend this class to add additional sink definitions. */ -class SinkModelCsv extends Unit { +deprecated class SinkModelCsv = SinkModelCsvInternal; + +private class SinkModelCsvInternal extends Unit { /** Holds if `row` specifies a sink definition. */ abstract predicate row(string row); } /** + * DEPRECATED: Define summary models as data extensions instead. + * * A unit class for adding additional summary model rows. * * Extend this class to add additional flow summary definitions. */ -class SummaryModelCsv extends Unit { +deprecated class SummaryModelCsv = SummaryModelCsvInternal; + +private class SummaryModelCsvInternal extends Unit { /** Holds if `row` specifies a summary definition. */ abstract predicate row(string row); } +private predicate sourceModelInternal(string row) { any(SourceModelCsvInternal s).row(row) } + +private predicate summaryModelInternal(string row) { any(SummaryModelCsvInternal s).row(row) } + +private predicate sinkModelInternal(string row) { any(SinkModelCsvInternal s).row(row) } + /** - * A unit class for adding negative summary model rows. + * A class for activating additional model rows. * - * Extend this class to add additional flow summary definitions. + * Extend this class to include experimental model rows with `this` name + * in data flow analysis. */ -class NegativeSummaryModelCsv extends Unit { - /** Holds if `row` specifies a negative summary definition. */ - abstract predicate row(string row); -} +abstract class ActiveExperimentalModels extends string { + bindingset[this] + ActiveExperimentalModels() { any() } -private class SourceModelCsvBase extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // org.springframework.security.web.savedrequest.SavedRequest - "org.springframework.security.web.savedrequest;SavedRequest;true;getRedirectUrl;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getCookies;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getHeaderValues;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getHeaderNames;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getParameterValues;;;ReturnValue;remote;manual", - "org.springframework.security.web.savedrequest;SavedRequest;true;getParameterMap;;;ReturnValue;remote;manual", - // ServletRequestGetParameterMethod - "javax.servlet;ServletRequest;false;getParameter;(String);;ReturnValue;remote;manual", - "javax.servlet;ServletRequest;false;getParameterValues;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameter;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterValues;(String);;ReturnValue;remote;manual", - // ServletRequestGetParameterMapMethod - "javax.servlet;ServletRequest;false;getParameterMap;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterMap;();;ReturnValue;remote;manual", - // ServletRequestGetParameterNamesMethod - "javax.servlet;ServletRequest;false;getParameterNames;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getParameterNames;();;ReturnValue;remote;manual", - // HttpServletRequestGetQueryStringMethod - "javax.servlet.http;HttpServletRequest;false;getQueryString;();;ReturnValue;remote;manual", - // - // URLConnectionGetInputStreamMethod - "java.net;URLConnection;false;getInputStream;();;ReturnValue;remote;manual", - // SocketGetInputStreamMethod - "java.net;Socket;false;getInputStream;();;ReturnValue;remote;manual", - // BeanValidationSource - "javax.validation;ConstraintValidator;true;isValid;;;Parameter[0];remote;manual", - // SpringMultipartRequestSource - "org.springframework.web.multipart;MultipartRequest;true;getFile;(String);;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileMap;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileNames;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFiles;(String);;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultiFileMap;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultipartContentType;(String);;ReturnValue;remote;manual", - // SpringMultipartFileSource - "org.springframework.web.multipart;MultipartFile;true;getBytes;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getContentType;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getInputStream;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getName;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getOriginalFilename;();;ReturnValue;remote;manual", - "org.springframework.web.multipart;MultipartFile;true;getResource;();;ReturnValue;remote;manual", - // HttpServletRequest.get* - "javax.servlet.http;HttpServletRequest;false;getHeader;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getHeaders;(String);;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getHeaderNames;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getPathInfo;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURI;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURL;();;ReturnValue;remote;manual", - "javax.servlet.http;HttpServletRequest;false;getRemoteUser;();;ReturnValue;remote;manual", - // SpringWebRequestGetMethod - "org.springframework.web.context.request;WebRequest;false;getDescription;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeader;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeaderNames;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getHeaderValues;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameter;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterMap;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterNames;;;ReturnValue;remote;manual", - "org.springframework.web.context.request;WebRequest;false;getParameterValues;;;ReturnValue;remote;manual", - // TODO consider org.springframework.web.context.request.WebRequest.getRemoteUser - // ServletRequestGetBodyMethod - "javax.servlet;ServletRequest;false;getInputStream;();;ReturnValue;remote;manual", - "javax.servlet;ServletRequest;false;getReader;();;ReturnValue;remote;manual", - // CookieGet* - "javax.servlet.http;Cookie;false;getValue;();;ReturnValue;remote;manual", - "javax.servlet.http;Cookie;false;getName;();;ReturnValue;remote;manual", - "javax.servlet.http;Cookie;false;getComment;();;ReturnValue;remote;manual", - // ApacheHttp* - "org.apache.http;HttpMessage;false;getParams;();;ReturnValue;remote;manual", - "org.apache.http;HttpEntity;false;getContent;();;ReturnValue;remote;manual", - // In the setting of Android we assume that XML has been transmitted over - // the network, so may be tainted. - // XmlPullGetMethod - "org.xmlpull.v1;XmlPullParser;false;getName;();;ReturnValue;remote;manual", - "org.xmlpull.v1;XmlPullParser;false;getNamespace;();;ReturnValue;remote;manual", - "org.xmlpull.v1;XmlPullParser;false;getText;();;ReturnValue;remote;manual", - // XmlAttrSetGetMethod - "android.util;AttributeSet;false;getAttributeBooleanValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeCount;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeFloatValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeIntValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeListValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeName;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeNameResource;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeNamespace;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeResourceValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeUnsignedIntValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getAttributeValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getClassAttribute;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getIdAttribute;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getIdAttributeResourceValue;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getPositionDescription;;;ReturnValue;remote;manual", - "android.util;AttributeSet;false;getStyleAttribute;;;ReturnValue;remote;manual", - // The current URL in a browser may be untrusted or uncontrolled. - // WebViewGetUrlMethod - "android.webkit;WebView;false;getUrl;();;ReturnValue;remote;manual", - "android.webkit;WebView;false;getOriginalUrl;();;ReturnValue;remote;manual", - // SpringRestTemplateResponseEntityMethod - "org.springframework.web.client;RestTemplate;false;exchange;;;ReturnValue;remote;manual", - "org.springframework.web.client;RestTemplate;false;getForEntity;;;ReturnValue;remote;manual", - "org.springframework.web.client;RestTemplate;false;postForEntity;;;ReturnValue;remote;manual", - // WebSocketMessageParameterSource - "java.net.http;WebSocket$Listener;true;onText;(WebSocket,CharSequence,boolean);;Parameter[1];remote;manual", - // PlayRequestGetMethod - "play.mvc;Http$RequestHeader;false;queryString;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;getQueryString;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;header;;;ReturnValue;remote;manual", - "play.mvc;Http$RequestHeader;false;getHeader;;;ReturnValue;remote;manual" - ] + /** + * Holds if an experimental source model exists for the given parameters. + */ + predicate sourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance + ) { + Extensions::experimentalSourceModel(package, type, subtypes, name, signature, ext, output, kind, + provenance, this) + } + + /** + * Holds if an experimental sink model exists for the given parameters. + */ + predicate sinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance + ) { + Extensions::experimentalSinkModel(package, type, subtypes, name, signature, ext, output, kind, + provenance, this) + } + + /** + * Holds if an experimental summary model exists for the given parameters. + */ + predicate summaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance + ) { + Extensions::experimentalSummaryModel(package, type, subtypes, name, signature, ext, input, + output, kind, provenance, this) } } -private class SinkModelCsvBase extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // Open URL - "java.net;URL;false;openConnection;;;Argument[-1];open-url;manual", - "java.net;URL;false;openStream;;;Argument[-1];open-url;manual", - "java.net.http;HttpRequest;false;newBuilder;;;Argument[0];open-url;manual", - "java.net.http;HttpRequest$Builder;false;uri;;;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[]);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader,URLStreamHandlerFactory);;Argument[0];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader);;Argument[1];open-url;manual", - "java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader,URLStreamHandlerFactory);;Argument[1];open-url;manual", - "java.net;URLClassLoader;false;newInstance;;;Argument[0];open-url;manual", - // Bean validation - "javax.validation;ConstraintValidatorContext;true;buildConstraintViolationWithTemplate;;;Argument[0];bean-validation;manual", - // Set hostname - "javax.net.ssl;HttpsURLConnection;true;setDefaultHostnameVerifier;;;Argument[0];set-hostname-verifier;manual", - "javax.net.ssl;HttpsURLConnection;true;setHostnameVerifier;;;Argument[0];set-hostname-verifier;manual" - ] - } -} - -private class SummaryModelCsvBase extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // qualifier to arg - "java.io;InputStream;true;read;(byte[]);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;read;(byte[],int,int);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;readNBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual", - "java.io;InputStream;true;transferTo;(OutputStream);;Argument[-1];Argument[0];taint;manual", - "java.io;ByteArrayOutputStream;false;writeTo;;;Argument[-1];Argument[0];taint;manual", - "java.io;Reader;true;read;;;Argument[-1];Argument[0];taint;manual", - // qualifier to return - "java.io;ByteArrayOutputStream;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual", - "java.io;ByteArrayOutputStream;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;InputStream;true;readAllBytes;;;Argument[-1];ReturnValue;taint;manual", - "java.io;InputStream;true;readNBytes;(int);;Argument[-1];ReturnValue;taint;manual", - "java.util;StringTokenizer;false;nextElement;();;Argument[-1];ReturnValue;taint;manual", - "java.util;StringTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "javax.xml.transform.sax;SAXSource;false;getInputSource;;;Argument[-1];ReturnValue;taint;manual", - "javax.xml.transform.stream;StreamSource;false;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "java.nio;ByteBuffer;false;get;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toURL;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.net;URI;false;toAsciiString;;;Argument[-1];ReturnValue;taint;manual", - "java.nio;ByteBuffer;false;array;();;Argument[-1];ReturnValue;taint;manual", - "java.io;BufferedReader;true;readLine;;;Argument[-1];ReturnValue;taint;manual", - "java.io;Reader;true;read;();;Argument[-1];ReturnValue;taint;manual", - // arg to return - "java.nio;ByteBuffer;false;wrap;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encode;(ByteBuffer);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;encodeToString;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Encoder;false;wrap;(OutputStream);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(ByteBuffer);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;decode;(String);;Argument[0];ReturnValue;taint;manual", - "java.util;Base64$Decoder;false;wrap;(InputStream);;Argument[0];ReturnValue;taint;manual", - "cn.hutool.core.codec;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual", - "org.apache.shiro.codec;Base64;false;decode;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;Encoder;true;encode;(Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;Decoder;true;decode;(Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;BinaryEncoder;true;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;BinaryDecoder;true;decode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;StringEncoder;true;encode;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.codec;StringDecoder;true;decode;(String);;Argument[0];ReturnValue;taint;manual", - "java.net;URLDecoder;false;decode;;;Argument[0];ReturnValue;taint;manual", - "java.net;URI;false;create;;;Argument[0];ReturnValue;taint;manual", - "javax.xml.transform.sax;SAXSource;false;sourceToInputSource;;;Argument[0];ReturnValue;taint;manual", - // arg to arg - "java.lang;System;false;arraycopy;;;Argument[0];Argument[2];taint;manual", - // constructor flow - "java.net;URI;false;URI;(String);;Argument[0];Argument[-1];taint;manual", - "java.net;URL;false;URL;(String);;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.stream;StreamSource;false;StreamSource;;;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.sax;SAXSource;false;SAXSource;(InputSource);;Argument[0];Argument[-1];taint;manual", - "javax.xml.transform.sax;SAXSource;false;SAXSource;(XMLReader,InputSource);;Argument[1];Argument[-1];taint;manual", - "org.xml.sax;InputSource;false;InputSource;;;Argument[0];Argument[-1];taint;manual", - "javax.servlet.http;Cookie;false;Cookie;;;Argument[0];Argument[-1];taint;manual", - "javax.servlet.http;Cookie;false;Cookie;;;Argument[1];Argument[-1];taint;manual", - "java.util.zip;ZipInputStream;false;ZipInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.util.zip;GZIPInputStream;false;GZIPInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.util;StringTokenizer;false;StringTokenizer;;;Argument[0];Argument[-1];taint;manual", - "java.beans;XMLDecoder;false;XMLDecoder;;;Argument[0];Argument[-1];taint;manual", - "com.esotericsoftware.kryo.io;Input;false;Input;;;Argument[0];Argument[-1];taint;manual", - "com.esotericsoftware.kryo5.io;Input;false;Input;;;Argument[0];Argument[-1];taint;manual", - "java.io;BufferedInputStream;false;BufferedInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;DataInputStream;false;DataInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;ByteArrayInputStream;false;ByteArrayInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;ObjectInputStream;false;ObjectInputStream;;;Argument[0];Argument[-1];taint;manual", - "java.io;StringReader;false;StringReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;CharArrayReader;false;CharArrayReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;BufferedReader;false;BufferedReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(byte[]);;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "java.io;OutputStream;true;write;(int);;Argument[0];Argument[-1];taint;manual", - "java.io;FilterOutputStream;true;FilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;manual" - ] - } -} - -/** Holds if `row` is a source model. */ -predicate sourceModel(string row) { any(SourceModelCsv s).row(row) } - -/** Holds if `row` is a sink model. */ -predicate sinkModel(string row) { any(SinkModelCsv s).row(row) } - -/** Holds if `row` is a summary model. */ -predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } - -/** Holds if `row` is negative summary model. */ -predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) } - /** Holds if a source model exists for the given parameters. */ predicate sourceModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string output, string kind, string provenance ) { exists(string row | - sourceModel(row) and - row.splitAt(";", 0) = namespace and + sourceModelInternal(row) and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and subtypes = [true, false] and @@ -448,16 +191,21 @@ predicate sourceModel( row.splitAt(";", 7) = kind and row.splitAt(";", 8) = provenance ) + or + Extensions::sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) + or + any(ActiveExperimentalModels q) + .sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) } /** Holds if a sink model exists for the given parameters. */ predicate sinkModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string input, string kind, string provenance ) { exists(string row | - sinkModel(row) and - row.splitAt(";", 0) = namespace and + sinkModelInternal(row) and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and row.splitAt(";", 2) = subtypes.toString() and subtypes = [true, false] and @@ -468,53 +216,47 @@ predicate sinkModel( row.splitAt(";", 7) = kind and row.splitAt(";", 8) = provenance ) + or + Extensions::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) + or + any(ActiveExperimentalModels q) + .sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) } /** Holds if a summary model exists for the given parameters. */ predicate summaryModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, + string package, string type, boolean subtypes, string name, string signature, string ext, string input, string output, string kind, string provenance -) { - summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance, _) -} - -/** Holds if a summary model `row` exists for the given parameters. */ -predicate summaryModel( - string namespace, string type, boolean subtypes, string name, string signature, string ext, - string input, string output, string kind, string provenance, string row -) { - summaryModel(row) and - row.splitAt(";", 0) = namespace and - row.splitAt(";", 1) = type and - row.splitAt(";", 2) = subtypes.toString() and - subtypes = [true, false] and - row.splitAt(";", 3) = name and - row.splitAt(";", 4) = signature and - row.splitAt(";", 5) = ext and - row.splitAt(";", 6) = input and - row.splitAt(";", 7) = output and - row.splitAt(";", 8) = kind and - row.splitAt(";", 9) = provenance -} - -/** Holds if a summary model exists indicating there is no flow for the given parameters. */ -predicate negativeSummaryModel( - string namespace, string type, string name, string signature, string provenance ) { exists(string row | - negativeSummaryModel(row) and - row.splitAt(";", 0) = namespace and + summaryModelInternal(row) and + row.splitAt(";", 0) = package and row.splitAt(";", 1) = type and - row.splitAt(";", 2) = name and - row.splitAt(";", 3) = signature and - row.splitAt(";", 4) = provenance + row.splitAt(";", 2) = subtypes.toString() and + subtypes = [true, false] and + row.splitAt(";", 3) = name and + row.splitAt(";", 4) = signature and + row.splitAt(";", 5) = ext and + row.splitAt(";", 6) = input and + row.splitAt(";", 7) = output and + row.splitAt(";", 8) = kind and + row.splitAt(";", 9) = provenance ) + or + Extensions::summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, + provenance) + or + any(ActiveExperimentalModels q) + .summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) } +/** Holds if a neutral model exists indicating there is no flow for the given parameters. */ +predicate neutralModel = Extensions::neutralModel/5; + private predicate relevantPackage(string package) { sourceModel(package, _, _, _, _, _, _, _, _) or sinkModel(package, _, _, _, _, _, _, _, _) or - summaryModel(package, _, _, _, _, _, _, _, _, _, _) + summaryModel(package, _, _, _, _, _, _, _, _, _) } private predicate packageLink(string shortpkg, string longpkg) { @@ -533,7 +275,7 @@ private predicate canonicalPkgLink(string package, string subpkg) { } /** - * Holds if CSV framework coverage of `package` is `n` api endpoints of the + * Holds if MaD framework coverage of `package` is `n` api endpoints of the * kind `(kind, part)`. */ predicate modelCoverage(string package, int pkgs, string kind, string part, int n) { @@ -565,8 +307,8 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int ) } -/** Provides a query predicate to check the CSV data for validation errors. */ -module CsvValidation { +/** Provides a query predicate to check the MaD models for validation errors. */ +module ModelValidation { private string getInvalidModelInput() { exists(string pred, string input, string part | sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" @@ -600,28 +342,26 @@ module CsvValidation { } private string getInvalidModelKind() { - exists(string row, string kind | summaryModel(row) | - kind = row.splitAt(";", 8) and + exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string row, string kind | sinkModel(row) | - kind = row.splitAt(";", 7) and + exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ "open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-open-stream", "url-redirect", "create-file", "write-file", "set-hostname-verifier", - "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti" + "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti", + "fragment-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or - exists(string row, string kind | sourceModel(row) | - kind = row.splitAt(";", 7) and + exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." @@ -630,11 +370,11 @@ module CsvValidation { private string getInvalidModelSubtype() { exists(string pred, string row | - sourceModel(row) and pred = "source" + sourceModelInternal(row) and pred = "source" or - sinkModel(row) and pred = "sink" + sinkModelInternal(row) and pred = "sink" or - summaryModel(row) and pred = "summary" + summaryModelInternal(row) and pred = "summary" | exists(string b | b = row.splitAt(";", 2) and @@ -646,13 +386,11 @@ module CsvValidation { private string getInvalidModelColumnCount() { exists(string pred, string row, int expect | - sourceModel(row) and expect = 9 and pred = "source" + sourceModelInternal(row) and expect = 9 and pred = "source" or - sinkModel(row) and expect = 9 and pred = "sink" + sinkModelInternal(row) and expect = 9 and pred = "sink" or - summaryModel(row) and expect = 10 and pred = "summary" - or - negativeSummaryModel(row) and expect = 5 and pred = "negative summary" + summaryModelInternal(row) and expect = 10 and pred = "summary" | exists(int cols | cols = 1 + max(int n | exists(row.splitAt(";", n))) and @@ -666,27 +404,27 @@ module CsvValidation { private string getInvalidModelSignature() { exists( - string pred, string namespace, string type, string name, string signature, string ext, + string pred, string package, string type, string name, string signature, string ext, string provenance | - sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source" + sourceModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "source" or - sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink" + sinkModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "sink" or - summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and + summaryModel(package, type, _, name, signature, ext, _, _, _, provenance) and pred = "summary" or - negativeSummaryModel(namespace, type, name, signature, provenance) and + neutralModel(package, type, name, signature, provenance) and ext = "" and - pred = "negative summary" + pred = "neutral" | - not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and - result = "Dubious namespace \"" + namespace + "\" in " + pred + " model." + not package.regexpMatch("[a-zA-Z0-9_\\.]*") and + result = "Dubious package \"" + package + "\" in " + pred + " model." or not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and result = "Dubious type \"" + type + "\" in " + pred + " model." or - not name.regexpMatch("[a-zA-Z0-9_]*") and + not name.regexpMatch("[a-zA-Z0-9_\\-]*") and result = "Dubious name \"" + name + "\" in " + pred + " model." or not signature.regexpMatch("|\\([a-zA-Z0-9_\\.\\$<>,\\[\\]]*\\)") and @@ -700,7 +438,7 @@ module CsvValidation { ) } - /** Holds if some row in a CSV-based flow model appears to contain typos. */ + /** Holds if some row in a MaD flow model appears to contain typos. */ query predicate invalidModelRow(string msg) { msg = [ @@ -712,15 +450,15 @@ module CsvValidation { pragma[nomagic] private predicate elementSpec( - string namespace, string type, boolean subtypes, string name, string signature, string ext + string package, string type, boolean subtypes, string name, string signature, string ext ) { - sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sourceModel(package, type, subtypes, name, signature, ext, _, _, _) or - sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) + sinkModel(package, type, subtypes, name, signature, ext, _, _, _) or - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) + summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _) or - negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false + neutralModel(package, type, name, signature, _) and ext = "" and subtypes = false } private string paramsStringPart(Callable c, int i) { @@ -745,10 +483,10 @@ cached string paramsString(Callable c) { result = concat(int i | | paramsStringPart(c, i) order by i) } private Element interpretElement0( - string namespace, string type, boolean subtypes, string name, string signature + string package, string type, boolean subtypes, string name, string signature ) { - elementSpec(namespace, type, subtypes, name, signature, _) and - exists(RefType t | t.hasQualifiedName(namespace, type) | + elementSpec(package, type, subtypes, name, signature, _) and + exists(RefType t | t.hasQualifiedName(package, type) | exists(Member m | ( result = m @@ -769,12 +507,12 @@ private Element interpretElement0( ) } -/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */ +/** Gets the source/sink/summary/neutral element corresponding to the supplied parameters. */ Element interpretElement( - string namespace, string type, boolean subtypes, string name, string signature, string ext + string package, string type, boolean subtypes, string name, string signature, string ext ) { - elementSpec(namespace, type, subtypes, name, signature, ext) and - exists(Element e | e = interpretElement0(namespace, type, subtypes, name, signature) | + elementSpec(package, type, subtypes, name, signature, ext) and + exists(Element e | e = interpretElement0(package, type, subtypes, name, signature) | ext = "" and result = e or ext = "Annotated" and result.(Annotatable).getAnAnnotation().getType() = e @@ -829,7 +567,7 @@ predicate parseContent(AccessPathToken component, Content content) { cached private module Cached { /** - * Holds if `node` is specified as a source with the given kind in a CSV flow + * Holds if `node` is specified as a source with the given kind in a MaD flow * model. */ cached @@ -838,7 +576,7 @@ private module Cached { } /** - * Holds if `node` is specified as a sink with the given kind in a CSV flow + * Holds if `node` is specified as a sink with the given kind in a MaD flow * model. */ cached diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlowExtensions.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlowExtensions.qll new file mode 100644 index 00000000000..b06dc92c427 --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlowExtensions.qll @@ -0,0 +1,61 @@ +/** + * This module provides extensible predicates for defining MaD models. + */ + +/** + * Holds if a source model exists for the given parameters. + */ +extensible predicate sourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance +); + +/** + * Holds if a sink model exists for the given parameters. + */ +extensible predicate sinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance +); + +/** + * Holds if a summary model exists for the given parameters. + */ +extensible predicate summaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance +); + +/** + * Holds if a neutral model exists indicating there is no flow for the given parameters. + */ +extensible predicate neutralModel( + string package, string type, string name, string signature, string provenance +); + +/** + * Holds if an experimental source model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate experimentalSourceModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance, string filter +); + +/** + * Holds if an experimental sink model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate experimentalSinkModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance, string filter +); + +/** + * Holds if an experimental summary model exists for the given parameters. + * This is only for experimental queries. + */ +extensible predicate experimentalSummaryModel( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance, string filter +); diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index fcb4ac3b970..4970b8ff642 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -36,6 +36,13 @@ abstract class RemoteFlowSource extends DataFlow::Node { abstract string getSourceType(); } +/** + * A module for importing frameworks that define remote flow sources. + */ +private module RemoteFlowSources { + private import semmle.code.java.frameworks.android.Widget +} + private class ExternalRemoteFlowSource extends RemoteFlowSource { ExternalRemoteFlowSource() { sourceNode(this, "remote") } @@ -165,9 +172,7 @@ abstract class UserInput extends DataFlow::Node { } /** * Input that may be controlled by a remote user. */ -private class RemoteUserInput extends UserInput { - RemoteUserInput() { this instanceof RemoteFlowSource } -} +private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { } /** A node with input that may be controlled by a local user. */ abstract class LocalUserInput extends UserInput { } diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll index 4f350ec9ccb..f6f1d92b195 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll @@ -10,17 +10,19 @@ private import semmle.code.java.dataflow.DataFlow * ensuring that they are visible to the taint tracking library. */ private module Frameworks { - private import semmle.code.java.JDK - private import semmle.code.java.frameworks.jackson.JacksonSerializability private import semmle.code.java.frameworks.android.AsyncTask private import semmle.code.java.frameworks.android.Intent + private import semmle.code.java.frameworks.android.Slice private import semmle.code.java.frameworks.android.SQLite - private import semmle.code.java.frameworks.Guice - private import semmle.code.java.frameworks.Properties - private import semmle.code.java.frameworks.Protobuf - private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.apache.Lang private import semmle.code.java.frameworks.ApacheHttp + private import semmle.code.java.frameworks.guava.Guava + private import semmle.code.java.frameworks.Guice + private import semmle.code.java.frameworks.jackson.JacksonSerializability + private import semmle.code.java.frameworks.Properties + private import semmle.code.java.frameworks.Protobuf + private import semmle.code.java.frameworks.ratpack.RatpackExec + private import semmle.code.java.JDK } /** diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll index 6b790e487c1..09a5f05914f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll @@ -6,11 +6,6 @@ import java private import internal.FlowSummaryImpl as Impl private import internal.DataFlowUtil -// import all instances of SummarizedCallable below -private module Summaries { - private import semmle.code.java.dataflow.ExternalFlow -} - class SummaryComponent = Impl::Public::SummaryComponent; /** Provides predicates for constructing summary components. */ @@ -102,6 +97,14 @@ abstract class SyntheticCallable extends string { Type getReturnType() { none() } } +/** + * A module for importing frameworks that define synthetic callables. + */ +private module SyntheticCallables { + private import semmle.code.java.frameworks.android.Intent + private import semmle.code.java.frameworks.Stream +} + private newtype TSummarizedCallableBase = TSimpleCallable(Callable c) { c.isSourceDeclaration() } or TSyntheticCallable(SyntheticCallable c) diff --git a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll index 4bc17e8c4b4..1c76f554020 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll @@ -53,16 +53,6 @@ private class TypeFlowNode extends TTypeFlowNode { } } -private int getNodeKind(TypeFlowNode n) { - result = 1 and n instanceof TField - or - result = 2 and n instanceof TSsa - or - result = 3 and n instanceof TExpr - or - result = 4 and n instanceof TMethod -} - /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */ private RefType boxIfNeeded(Type t) { t.(PrimitiveType).getBoxedType() = result or @@ -158,107 +148,45 @@ private predicate joinStep(TypeFlowNode n1, TypeFlowNode n2) { private predicate anyStep(TypeFlowNode n1, TypeFlowNode n2) { joinStep(n1, n2) or step(n1, n2) } -private import SccReduction +private predicate sccEdge(TypeFlowNode n1, TypeFlowNode n2) { anyStep(n1, n2) and anyStep+(n2, n1) } -/** - * SCC reduction. - * - * This ought to be as easy as `equivalenceRelation(sccEdge/2)(n, scc)`, but - * this HOP is not currently supported for newtypes. - * - * A straightforward implementation would be: - * ```ql - * predicate sccRepr(TypeFlowNode n, TypeFlowNode scc) { - * scc = - * max(TypeFlowNode n2 | - * sccEdge+(n, n2) - * | - * n2 - * order by - * n2.getLocation().getStartLine(), n2.getLocation().getStartColumn(), getNodeKind(n2) - * ) - * } - * - * ``` - * but this is quadratic in the size of the SCCs. - * - * Instead we find local maxima by following SCC edges and determine the SCC - * representatives from those. - * (This is still worst-case quadratic in the size of the SCCs, but generally - * performs better.) - */ -private module SccReduction { - private predicate sccEdge(TypeFlowNode n1, TypeFlowNode n2) { - anyStep(n1, n2) and anyStep+(n2, n1) - } +private module Scc = QlBuiltins::EquivalenceRelation; - private predicate sccEdgeWithMax(TypeFlowNode n1, TypeFlowNode n2, TypeFlowNode m) { - sccEdge(n1, n2) and - m = - max(TypeFlowNode n | - n = [n1, n2] - | - n order by n.getLocation().getStartLine(), n.getLocation().getStartColumn(), getNodeKind(n) - ) - } +private class TypeFlowScc = Scc::EquivalenceClass; - private predicate hasLargerNeighbor(TypeFlowNode n) { - exists(TypeFlowNode n2 | - sccEdgeWithMax(n, n2, n2) and - not sccEdgeWithMax(n, n2, n) - or - sccEdgeWithMax(n2, n, n2) and - not sccEdgeWithMax(n2, n, n) - ) - } +/** Holds if `n` is part of an SCC of size 2 or more represented by `scc`. */ +private predicate sccRepr(TypeFlowNode n, TypeFlowScc scc) { scc = Scc::getEquivalenceClass(n) } - private predicate localMax(TypeFlowNode m) { - sccEdgeWithMax(_, _, m) and - not hasLargerNeighbor(m) - } - - private predicate sccReprFromLocalMax(TypeFlowNode scc) { - exists(TypeFlowNode m | - localMax(m) and - scc = - max(TypeFlowNode n2 | - sccEdge+(m, n2) and localMax(n2) - | - n2 - order by - n2.getLocation().getStartLine(), n2.getLocation().getStartColumn(), getNodeKind(n2) - ) - ) - } - - /** Holds if `n` is part of an SCC of size 2 or more represented by `scc`. */ - predicate sccRepr(TypeFlowNode n, TypeFlowNode scc) { - sccEdge+(n, scc) and sccReprFromLocalMax(scc) - } - - predicate sccJoinStep(TypeFlowNode n, TypeFlowNode scc) { - exists(TypeFlowNode mid | - joinStep(n, mid) and - sccRepr(mid, scc) and - not sccRepr(n, scc) - ) - } +private predicate sccJoinStep(TypeFlowNode n, TypeFlowScc scc) { + exists(TypeFlowNode mid | + joinStep(n, mid) and + sccRepr(mid, scc) and + not sccRepr(n, scc) + ) } -private signature predicate edgeSig(TypeFlowNode n1, TypeFlowNode n2); +private signature class NodeSig; -private signature module RankedEdge { - predicate edgeRank(int r, TypeFlowNode n1, TypeFlowNode n2); +private signature module Edge { + class Node; - int lastRank(TypeFlowNode n); + predicate edge(TypeFlowNode n1, Node n2); } -private module RankEdge implements RankedEdge { +private signature module RankedEdge { + predicate edgeRank(int r, TypeFlowNode n1, Node n2); + + int lastRank(Node n); +} + +private module RankEdge implements RankedEdge { + private import E + /** * Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. The used * ordering is not necessarily total, so the ranking may have gaps. */ - private predicate edgeRank1(int r, TypeFlowNode n1, TypeFlowNode n2) { + private predicate edgeRank1(int r, TypeFlowNode n1, Node n2) { n1 = rank[r](TypeFlowNode n | edge(n, n2) @@ -271,19 +199,19 @@ private module RankEdge implements RankedEdge { * Holds if `r2` is a ranking of the ranks from `edgeRank1`. This removes the * gaps from the ranking. */ - private predicate edgeRank2(int r2, int r1, TypeFlowNode n) { + private predicate edgeRank2(int r2, int r1, Node n) { r1 = rank[r2](int r | edgeRank1(r, _, n) | r) } /** Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. */ - predicate edgeRank(int r, TypeFlowNode n1, TypeFlowNode n2) { + predicate edgeRank(int r, TypeFlowNode n1, Node n2) { exists(int r1 | edgeRank1(r1, n1, n2) and edgeRank2(r, r1, n2) ) } - int lastRank(TypeFlowNode n) { result = max(int r | edgeRank(r, _, n)) } + int lastRank(Node n) { result = max(int r | edgeRank(r, _, n)) } } private signature module TypePropagation { @@ -296,16 +224,16 @@ private signature module TypePropagation { } /** Implements recursion through `forall` by way of edge ranking. */ -private module ForAll { +private module ForAll E, TypePropagation T> { /** * Holds if `t` is a bound that holds on one of the incoming edges to `n` and * thus is a candidate bound for `n`. */ pragma[nomagic] - private predicate candJoinType(TypeFlowNode n, T::Typ t) { + private predicate candJoinType(Node n, T::Typ t) { exists(TypeFlowNode mid | T::candType(mid, t) and - Edge::edgeRank(_, mid, n) + E::edgeRank(_, mid, n) ) } @@ -314,13 +242,13 @@ private module ForAll { * through the edges into `n` ranked from `1` to `r`. */ pragma[assume_small_delta] - private predicate flowJoin(int r, TypeFlowNode n, T::Typ t) { + private predicate flowJoin(int r, Node n, T::Typ t) { ( r = 1 and candJoinType(n, t) or - flowJoin(r - 1, n, t) and Edge::edgeRank(r, _, n) + flowJoin(r - 1, n, t) and E::edgeRank(r, _, n) ) and - forall(TypeFlowNode mid | Edge::edgeRank(r, mid, n) | T::supportsType(mid, t)) + forall(TypeFlowNode mid | E::edgeRank(r, mid, n) | T::supportsType(mid, t)) } /** @@ -328,12 +256,24 @@ private module ForAll { * coming through all the incoming edges, and therefore is a valid bound for * `n`. */ - predicate flowJoin(TypeFlowNode n, T::Typ t) { flowJoin(Edge::lastRank(n), n, t) } + predicate flowJoin(Node n, T::Typ t) { flowJoin(E::lastRank(n), n, t) } } -module RankedJoinStep = RankEdge; +private module JoinStep implements Edge { + class Node = TypeFlowNode; -module RankedSccJoinStep = RankEdge; + predicate edge = joinStep/2; +} + +private module SccJoinStep implements Edge { + class Node = TypeFlowScc; + + predicate edge = sccJoinStep/2; +} + +private module RankedJoinStep = RankEdge; + +private module RankedSccJoinStep = RankEdge; private predicate exactTypeBase(TypeFlowNode n, RefType t) { exists(ClassInstanceExpr e | @@ -363,13 +303,13 @@ private predicate exactType(TypeFlowNode n, RefType t) { or // The following is an optimized version of // `forex(TypeFlowNode mid | joinStep(mid, n) | exactType(mid, t))` - ForAll::flowJoin(n, t) + ForAll::flowJoin(n, t) or - exists(TypeFlowNode scc | + exists(TypeFlowScc scc | sccRepr(n, scc) and // Optimized version of // `forex(TypeFlowNode mid | sccJoinStep(mid, scc) | exactType(mid, t))` - ForAll::flowJoin(scc, t) + ForAll::flowJoin(scc, t) ) } @@ -563,11 +503,11 @@ private predicate typeFlow(TypeFlowNode n, RefType t) { or exists(TypeFlowNode mid | typeFlow(mid, t) and step(mid, n)) or - ForAll::flowJoin(n, t) + ForAll::flowJoin(n, t) or - exists(TypeFlowNode scc | + exists(TypeFlowScc scc | sccRepr(n, scc) and - ForAll::flowJoin(scc, t) + ForAll::flowJoin(scc, t) ) } @@ -703,13 +643,13 @@ private predicate hasUnionTypeFlow(TypeFlowNode n) { ( // Optimized version of // `forex(TypeFlowNode mid | joinStep(mid, n) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))` - ForAll::flowJoin(n, _) + ForAll::flowJoin(n, _) or - exists(TypeFlowNode scc | + exists(TypeFlowScc scc | sccRepr(n, scc) and // Optimized version of // `forex(TypeFlowNode mid | sccJoinStep(mid, scc) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))` - ForAll::flowJoin(scc, _) + ForAll::flowJoin(scc, _) ) or exists(TypeFlowNode mid | step(mid, n) and hasUnionTypeFlow(mid)) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index 8f9a40ed8d0..b53138c7421 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -3,7 +3,6 @@ import semmle.code.java.Collections import semmle.code.java.Maps private import semmle.code.java.dataflow.SSA private import DataFlowUtil -private import semmle.code.java.dataflow.ExternalFlow private class EntryType extends RefType { EntryType() { @@ -91,356 +90,6 @@ class ContainerType extends RefType { } } -private class ContainerFlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Object;true;clone;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.lang;Object;true;clone;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.lang;Object;true;clone;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Map$Entry;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - "java.util;Map$Entry;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map$Entry;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map$Entry;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - "java.lang;Iterable;true;iterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.lang;Iterable;true;spliterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.lang;Iterable;true;forEach;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Iterator;true;next;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Iterator;true;forEachRemaining;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;ListIterator;true;previous;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;ListIterator;true;add;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;ListIterator;true;set;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Enumeration;true;asIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Enumeration;true;nextElement;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;ReturnValue;value;manual", - "java.util;Map;true;computeIfAbsent;;;Argument[1].ReturnValue;Argument[-1].MapValue;value;manual", - "java.util;Map;true;entrySet;;;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "java.util;Map;true;entrySet;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - "java.util;Map;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;getOrDefault;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;getOrDefault;;;Argument[1];ReturnValue;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;putIfAbsent;;;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;replace;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;replace;(Object,Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Map;true;replace;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "java.util;Map;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "java.util;Map;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Map;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;Map;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;Map;true;forEach;(BiConsumer);;Argument[-1].MapKey;Argument[0].Parameter[0];value;manual", - "java.util;Map;true;forEach;(BiConsumer);;Argument[-1].MapValue;Argument[0].Parameter[1];value;manual", - "java.util;Collection;true;parallelStream;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Collection;true;stream;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Collection;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "java.util;Collection;true;toArray;;;Argument[-1].Element;Argument[0].ArrayElement;value;manual", - "java.util;Collection;true;add;;;Argument[0];Argument[-1].Element;value;manual", - "java.util;Collection;true;addAll;;;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;List;true;get;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;listIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;List;true;remove;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;set;(int,Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;List;true;set;(int,Object);;Argument[1];Argument[-1].Element;value;manual", - "java.util;List;true;subList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;List;true;add;(int,Object);;Argument[1];Argument[-1].Element;value;manual", - "java.util;List;true;addAll;(int,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - "java.util;Vector;true;elementAt;(int);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;elements;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Vector;true;firstElement;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;lastElement;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Vector;true;addElement;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Vector;true;copyInto;(Object[]);;Argument[-1].Element;Argument[0].ArrayElement;value;manual", - "java.util;Stack;true;peek;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Stack;true;pop;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Stack;true;push;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Queue;true;element;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;peek;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;poll;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;remove;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Queue;true;offer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;descendingIterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Deque;true;getFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;getLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;peekFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;peekLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pollFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pollLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;pop;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;removeFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;removeLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Deque;true;push;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;offerLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;offerFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;addLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;Deque;true;addFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;takeFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingDeque;true;takeLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;take;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Argument[-1].Element;Argument[0].Element;value;manual", - "java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Argument[-1].Element;Argument[0].Element;value;manual", - "java.util.concurrent;ConcurrentHashMap;true;elements;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;elements;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;get;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Dictionary;true;keys;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Dictionary;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Dictionary;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;ceilingEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;descendingMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;descendingMap;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;firstEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;firstEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;floorEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;floorEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;headMap;(Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;higherEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;higherEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;lastEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;lastEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;lowerEntry;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;pollFirstEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;pollFirstEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;pollLastEntry;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;pollLastEntry;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;NavigableMap;true;tailMap;(Object,boolean);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;NavigableSet;true;ceiling;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;descendingIterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;descendingSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;floor;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;headSet;(Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;higher;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;lower;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;pollFirst;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;pollLast;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;NavigableSet;true;tailSet;(Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;Properties;true;setProperty;(String,String);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", - "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextBoolean;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextDouble;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextFloat;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextLine;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual", - "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual", - "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedMap;true;tailMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "java.util;SortedMap;true;tailMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "java.util;SortedSet;true;first;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;SortedSet;true;headSet;(Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;SortedSet;true;last;();;Argument[-1].Element;ReturnValue;value;manual", - "java.util;SortedSet;true;subSet;(Object,Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;SortedSet;true;tailSet;(Object);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Argument[-1].Element;value;manual", - "java.util;List;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object);;Argument[0..1];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object);;Argument[0..2];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object);;Argument[0..3];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];ReturnValue.Element;value;manual", - "java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];ReturnValue.Element;value;manual", - "java.util;Map;false;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Map;false;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Map;false;entry;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Map;false;entry;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[10];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[11];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[12];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[13];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[14];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[15];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[16];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[17];ReturnValue.MapValue;value;manual", - "java.util;Map;false;of;;;Argument[18];ReturnValue.MapKey;value;manual", - "java.util;Map;false;of;;;Argument[19];ReturnValue.MapValue;value;manual", - "java.util;Map;false;ofEntries;;;Argument[0].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - "java.util;Map;false;ofEntries;;;Argument[0].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - "java.util;Set;false;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object);;Argument[0..1];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object);;Argument[0..2];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0..3];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];ReturnValue.Element;value;manual", - "java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];ReturnValue.Element;value;manual", - "java.util;Arrays;false;stream;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Arrays;false;spliterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Arrays;false;copyOfRange;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "java.util;Arrays;false;copyOf;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "java.util;Collections;false;list;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;enumeration;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;nCopies;(int,Object);;Argument[1];ReturnValue.Element;value;manual", - "java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "java.util;Collections;false;singletonList;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Collections;false;singleton;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;checkedMap;(Map,Class,Class);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;checkedList;(List,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedSet;(Set,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;checkedCollection;(Collection,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;synchronizedMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;synchronizedList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;synchronizedCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "java.util;Collections;false;unmodifiableMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "java.util;Collections;false;unmodifiableList;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;unmodifiableCollection;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "java.util;Collections;false;max;;;Argument[0].Element;ReturnValue;value;manual", - "java.util;Collections;false;min;;;Argument[0].Element;ReturnValue;value;manual", - "java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(Object[],Object);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(float[],float);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(double[],double);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(byte[],byte);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(char[],char);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(short[],short);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(int[],int);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];Argument[0].ArrayElement;value;manual", - "java.util;Arrays;false;fill;(long[],long);;Argument[1];Argument[0].ArrayElement;value;manual", - "java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Argument[0].Element;value;manual", - "java.util;Collections;false;copy;(List,List);;Argument[1].Element;Argument[0].Element;value;manual", - "java.util;Collections;false;fill;(List,Object);;Argument[1];Argument[0].Element;value;manual", - "java.util;Arrays;false;asList;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util;Collections;false;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleEntry;false;SimpleEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;AbstractMap$SimpleImmutableEntry;false;SimpleImmutableEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;ArrayDeque;false;ArrayDeque;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;ArrayList;false;ArrayList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;EnumMap;false;EnumMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;EnumMap;false;EnumMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;EnumMap;false;EnumMap;(EnumMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;EnumMap;false;EnumMap;(EnumMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;HashMap;false;HashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;HashMap;false;HashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;HashSet;false;HashSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;Hashtable;false;Hashtable;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;Hashtable;false;Hashtable;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;IdentityHashMap;false;IdentityHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;IdentityHashMap;false;IdentityHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;LinkedHashMap;false;LinkedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;LinkedHashMap;false;LinkedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;LinkedHashSet;false;LinkedHashSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;LinkedList;false;LinkedList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(PriorityQueue);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;PriorityQueue;false;PriorityQueue;(SortedSet);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;TreeMap;false;TreeMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;TreeMap;false;TreeMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;TreeMap;false;TreeMap;(SortedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;TreeMap;false;TreeMap;(SortedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "java.util;TreeSet;false;TreeSet;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;TreeSet;false;TreeSet;(SortedSet);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;Vector;false;Vector;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - "java.util;WeakHashMap;false;WeakHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "java.util;WeakHashMap;false;WeakHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - private predicate taintPreservingQualifierToMethod(Method m) { // java.util.Map.Entry m.getDeclaringType() instanceof EntryType and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index ae9c6f3f12e..9aa6a529a5b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -915,18 +915,57 @@ private module Cached { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) + cached + newtype TParamNodeOption = + TParamNodeNone() or + TParamNodeSome(ParamNode p) + + cached + newtype TReturnCtx = + TReturnCtxNone() or + TReturnCtxNoFlowThrough() or + TReturnCtxMaybeFlowThrough(ReturnPosition pos) + + cached + newtype TTypedContentApprox = + MkTypedContentApprox(ContentApprox c, DataFlowType t) { + exists(Content cont | + c = getContentApprox(cont) and + store(_, cont, _, _, t) + ) + } + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } + cached + TypedContent getATypedContent(TypedContentApprox c) { + exists(ContentApprox cls, DataFlowType t, Content cont | + c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and + result = MkTypedContent(cont, pragma[only_bind_into](t)) and + cls = getContentApprox(cont) + ) + } + cached newtype TAccessPathFront = TFrontNil(DataFlowType t) or TFrontHead(TypedContent tc) + cached + newtype TApproxAccessPathFront = + TApproxFrontNil(DataFlowType t) or + TApproxFrontHead(TypedContentApprox tc) + cached newtype TAccessPathFrontOption = TAccessPathFrontNone() or TAccessPathFrontSome(AccessPathFront apf) + + cached + newtype TApproxAccessPathFrontOption = + TApproxAccessPathFrontNone() or + TApproxAccessPathFrontSome(ApproxAccessPathFront apf) } /** @@ -1304,6 +1343,113 @@ class DataFlowCallOption extends TDataFlowCallOption { } } +/** An optional `ParamNode`. */ +class ParamNodeOption extends TParamNodeOption { + string toString() { + this = TParamNodeNone() and + result = "(none)" + or + exists(ParamNode p | + this = TParamNodeSome(p) and + result = p.toString() + ) + } +} + +/** + * A return context used to calculate flow summaries in reverse flow. + * + * The possible values are: + * + * - `TReturnCtxNone()`: no return flow. + * - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible. + * - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and + * flow through may be possible. + */ +class ReturnCtx extends TReturnCtx { + string toString() { + this = TReturnCtxNone() and + result = "(none)" + or + this = TReturnCtxNoFlowThrough() and + result = "(no flow through)" + or + exists(ReturnPosition pos | + this = TReturnCtxMaybeFlowThrough(pos) and + result = pos.toString() + ) + } +} + +/** An approximated `Content` tagged with the type of a containing object. */ +class TypedContentApprox extends MkTypedContentApprox { + private ContentApprox c; + private DataFlowType t; + + TypedContentApprox() { this = MkTypedContentApprox(c, t) } + + /** Gets a typed content approximated by this value. */ + TypedContent getATypedContent() { result = getATypedContent(this) } + + /** Gets the container type. */ + DataFlowType getContainerType() { result = t } + + /** Gets a textual representation of this approximated content. */ + string toString() { result = c.toString() } +} + +/** + * The front of an approximated access path. This is either a head or a nil. + */ +abstract class ApproxAccessPathFront extends TApproxAccessPathFront { + abstract string toString(); + + abstract DataFlowType getType(); + + abstract boolean toBoolNonEmpty(); + + pragma[nomagic] + TypedContent getAHead() { + exists(TypedContentApprox cont | + this = TApproxFrontHead(cont) and + result = cont.getATypedContent() + ) + } +} + +class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil { + private DataFlowType t; + + ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) } + + override string toString() { result = ppReprType(t) } + + override DataFlowType getType() { result = t } + + override boolean toBoolNonEmpty() { result = false } +} + +class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead { + private TypedContentApprox tc; + + ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) } + + override string toString() { result = tc.toString() } + + override DataFlowType getType() { result = tc.getContainerType() } + + override boolean toBoolNonEmpty() { result = true } +} + +/** An optional approximated access path front. */ +class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption { + string toString() { + this = TApproxAccessPathFrontNone() and result = "" + or + this = TApproxAccessPathFrontSome(any(ApproxAccessPathFront apf | result = apf.toString())) + } +} + /** A `Content` tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; @@ -1336,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront { abstract DataFlowType getType(); - abstract boolean toBoolNonEmpty(); + abstract ApproxAccessPathFront toApprox(); TypedContent getHead() { this = TFrontHead(result) } } @@ -1350,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil { override DataFlowType getType() { result = t } - override boolean toBoolNonEmpty() { result = false } + override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) } } class AccessPathFrontHead extends AccessPathFront, TFrontHead { @@ -1362,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead { override DataFlowType getType() { result = tc.getContainerType() } - override boolean toBoolNonEmpty() { result = true } + override ApproxAccessPathFront toApprox() { result.getAHead() = tc } } /** An optional access path front. */ diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll index dde16ab5a2a..e85e0cd92ec 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll @@ -136,6 +136,18 @@ module Consistency { msg = "Local flow step does not preserve enclosing callable." } + query predicate readStepIsLocal(Node n1, Node n2, string msg) { + readStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Read step does not preserve enclosing callable." + } + + query predicate storeStepIsLocal(Node n1, Node n2, string msg) { + storeStep(n1, _, n2) and + nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and + msg = "Store step does not preserve enclosing callable." + } + private DataFlowType typeRepr() { result = getNodeType(_) } query predicate compatibleTypesReflexive(DataFlowType t, string msg) { @@ -232,4 +244,25 @@ module Consistency { not callable = viableCallable(call) and not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) } + + query predicate uniqueParameterNodeAtPosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and + msg = "Parameters with overlapping positions." + } + + query predicate uniqueParameterNodePosition( + DataFlowCallable c, ParameterPosition pos, Node p, string msg + ) { + isParameterNode(p, c, pos) and + not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and + msg = "Parameter node with multiple positions." + } + + query predicate uniqueContentApprox(Content c, string msg) { + not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and + msg = "Non-unique content approximation." + } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 2dde1c2819d..1228d00b6ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -70,7 +70,7 @@ abstract class Configuration extends string { /** * Holds if `sink` is a relevant data flow sink accepting `state`. */ - predicate isSink(Node source, FlowState state) { none() } + predicate isSink(Node sink, FlowState state) { none() } /** * Holds if data flow through `node` is prohibited. This completely removes @@ -147,6 +147,12 @@ abstract class Configuration extends string { */ FlowFeature getAFeature() { none() } + /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + predicate sourceGrouping(Node source, string sourceGroup) { none() } + + /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + predicate sinkGrouping(Node sink, string sinkGroup) { none() } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -158,7 +164,7 @@ abstract class Configuration extends string { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) } + predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } /** * Holds if data may flow from some source to `sink` for this configuration. @@ -313,8 +319,6 @@ private class ParamNodeEx extends NodeEx { } ParameterPosition getPosition() { this.isParameterOf(_, result) } - - predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) } } private class RetNodeEx extends NodeEx { @@ -602,8 +606,27 @@ private predicate hasSinkCallCtx(Configuration config) { ) } +/** + * Holds if flow from `p` to a return node of kind `kind` is allowed. + * + * We don't expect a parameter to return stored in itself, unless + * explicitly allowed + */ +bindingset[p, kind] +private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind) { + exists(ParameterPosition pos | p.isParameterOf(_, pos) | + not kind.(ParamUpdateReturnKind).getPosition() = pos + or + allowParameterReturnInSelfCached(p.asNode()) + ) +} + private module Stage1 implements StageSig { - class Ap = Unit; + class Ap extends int { + // workaround for bad functionality-induced joins (happens when using `Unit`) + pragma[nomagic] + Ap() { this in [0 .. 1] and this < 1 } + } private class Cc = boolean; @@ -944,6 +967,12 @@ private module Stage1 implements StageSig { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, config) and + exists(ap) + } + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config) { revFlow(node, _, pragma[only_bind_into](config)) and @@ -975,21 +1004,26 @@ private module Stage1 implements StageSig { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(ReturnKindExt kind | + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p, config) and returnFlowCallableNodeCand(c, kind, config) and p.getEnclosingCallable() = c and exists(ap) and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition() - or - p.allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(p, kind) ) } + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + throughFlowNodeCand(ret, config) and + kind = ret.getKind() and + exists(argAp) and + exists(ap) + } + pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { exists(ArgNodeEx arg, boolean toReturn | @@ -1046,12 +1080,16 @@ private predicate viableReturnPosOutNodeCand1( */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, Configuration config ) { - viableReturnPosOutNodeCand1(call, ret.getReturnPosition(), out, config) and - Stage1::revFlow(ret, config) and - not outBarrier(ret, config) and - not inBarrier(out, config) + exists(ReturnPosition pos | + viableReturnPosOutNodeCand1(call, pos, out, config) and + pos = ret.getReturnPosition() and + kind = pos.getKind() and + Stage1::revFlow(ret, config) and + not outBarrier(ret, config) and + not inBarrier(out, config) + ) } pragma[nomagic] @@ -1081,10 +1119,11 @@ private predicate flowIntoCallNodeCand1( * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int branch(NodeEx n1, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n1, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) + flowOutOfCallNodeCand1(_, n1, _, n, conf) or flowIntoCallNodeCand1(_, n1, n, conf) ) } @@ -1093,10 +1132,11 @@ private int branch(NodeEx n1, Configuration conf) { * edge in the graph of paths between sources and sinks that ignores call * contexts. */ +pragma[nomagic] private int join(NodeEx n2, Configuration conf) { result = strictcount(NodeEx n | - flowOutOfCallNodeCand1(_, n, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) + flowOutOfCallNodeCand1(_, n, _, n2, conf) or flowIntoCallNodeCand1(_, n, n2, conf) ) } @@ -1109,12 +1149,13 @@ private int join(NodeEx n2, Configuration conf) { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, ret, out, config) and + flowOutOfCallNodeCand1(call, ret, kind, out, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(ret, config) and - j = join(out, config) and + b = branch(ret, pragma[only_bind_into](config)) and + j = join(out, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1130,10 +1171,10 @@ pragma[nomagic] private predicate flowIntoCallNodeCand1( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCallNodeCand1(call, arg, p, config) and + flowIntoCallNodeCand1(call, arg, p, pragma[only_bind_into](config)) and exists(int b, int j | - b = branch(arg, config) and - j = join(p, config) and + b = branch(arg, pragma[only_bind_into](config)) and + j = join(p, pragma[only_bind_into](config)) and if b.minimum(j) <= config.fieldFlowBranchLimit() then allowsFieldFlow = true else allowsFieldFlow = false @@ -1145,12 +1186,18 @@ private signature module StageSig { predicate revFlow(NodeEx node, Configuration config); + predicate revFlowAp(NodeEx node, Ap ap, Configuration config); + bindingset[node, state, config] predicate revFlow(NodeEx node, FlowState state, Ap ap, Configuration config); predicate callMayFlowThroughRev(DataFlowCall call, Configuration config); - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config); + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config); + + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ); predicate storeStepCand( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType, @@ -1216,7 +1263,8 @@ private module MkStage { ); predicate flowOutOfCall( - DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + Configuration config ); predicate flowIntoCall( @@ -1234,21 +1282,43 @@ private module MkStage { import Param /* Begin: Stage logic. */ - bindingset[result, apa] - private ApApprox unbindApa(ApApprox apa) { - pragma[only_bind_out](apa) = pragma[only_bind_out](result) + // use an alias as a workaround for bad functionality-induced joins + pragma[nomagic] + private predicate revFlowApAlias(NodeEx node, ApApprox apa, Configuration config) { + PrevStage::revFlowAp(node, apa, config) + } + + pragma[nomagic] + private predicate flowIntoCallApa( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, ApApprox apa, + Configuration config + ) { + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + PrevStage::revFlowAp(p, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(arg, pragma[only_bind_into](apa), pragma[only_bind_into](config)) + } + + pragma[nomagic] + private predicate flowOutOfCallApa( + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow, + ApApprox apa, Configuration config + ) { + flowOutOfCall(call, ret, kind, out, allowsFieldFlow, config) and + PrevStage::revFlowAp(out, pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + revFlowApAlias(ret, pragma[only_bind_into](apa), pragma[only_bind_into](config)) } pragma[nomagic] private predicate flowThroughOutOfCall( DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - Configuration config + ApApprox argApa, ApApprox apa, Configuration config ) { - flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and - PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _, - pragma[only_bind_into](config)) and - matchesCall(ccc, call) + exists(ReturnKindExt kind | + flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) and + matchesCall(ccc, call) + ) } /** @@ -1256,99 +1326,134 @@ private module MkStage { * configuration `config`. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `argAp` records the access path of that - * argument. + * argument in a call, and if so, `summaryCtx` and `argAp` record the + * corresponding parameter position and access path of that argument, respectively. */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { - fwdFlow0(node, state, cc, argAp, ap, config) and - PrevStage::revFlow(node, state, unbindApa(getApprox(ap)), config) and + fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and + PrevStage::revFlow(node, state, apa, config) and filter(node, state, ap, config) } + pragma[inline] + additional predicate fwdFlow( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + Configuration config + ) { + fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config) + } + pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap, + ApApprox apa, Configuration config ) { sourceNode(node, state, config) and (if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and argAp = apNone() and - ap = getApNil(node) + summaryCtx = TParamNodeNone() and + ap = getApNil(node) and + apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Ap ap0, LocalCc localCc | - fwdFlow(mid, state0, cc, argAp, ap0, config) and + exists(NodeEx mid, FlowState state0, Ap ap0, ApApprox apa0, LocalCc localCc | + fwdFlow(mid, state0, cc, summaryCtx, argAp, ap0, apa0, config) and localCc = getLocalCc(mid, cc) | localStep(mid, state0, node, state, true, _, config, localCc) and - ap = ap0 + ap = ap0 and + apa = apa0 or localStep(mid, state0, node, state, false, ap, config, localCc) and - ap0 instanceof ApNil + ap0 instanceof ApNil and + apa = getApprox(ap) ) or exists(NodeEx mid | - fwdFlow(mid, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and jumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(mid, state, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStep(mid, node, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(mid, state0, _, _, nil, pragma[only_bind_into](config)) and + fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and additionalJumpStateStep(mid, state0, node, state, config) and cc = ccNone() and + summaryCtx = TParamNodeNone() and argAp = apNone() and - ap = getApNil(node) + ap = getApNil(node) and + apa = getApprox(ap) ) or // store exists(TypedContent tc, Ap ap0 | - fwdFlowStore(_, ap0, tc, node, state, cc, argAp, config) and - ap = apCons(tc, ap0) + fwdFlowStore(_, ap0, tc, node, state, cc, summaryCtx, argAp, config) and + ap = apCons(tc, ap0) and + apa = getApprox(ap) ) or // read exists(Ap ap0, Content c | - fwdFlowRead(ap0, c, _, node, state, cc, argAp, config) and - fwdFlowConsCand(ap0, c, ap, config) + fwdFlowRead(ap0, c, _, node, state, cc, summaryCtx, argAp, config) and + fwdFlowConsCand(ap0, c, ap, config) and + apa = getApprox(ap) ) or // flow into a callable - exists(ApApprox apa | - fwdFlowIn(_, node, state, _, cc, _, ap, config) and - apa = getApprox(ap) and - if PrevStage::parameterMayFlowThrough(node, _, apa, config) - then argAp = apSome(ap) - else argAp = apNone() + fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and + if PrevStage::parameterMayFlowThrough(node, apa, config) + then ( + summaryCtx = TParamNodeSome(node.asNode()) and + argAp = apSome(ap) + ) else ( + summaryCtx = TParamNodeNone() and argAp = apNone() ) or // flow out of a callable - fwdFlowOutNotFromArg(node, state, cc, argAp, ap, config) + exists( + DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | + fwdFlow(ret, state, innercc, summaryCtx, argAp, ap, apa, config) and + flowOutOfCallApa(call, ret, _, node, allowsFieldFlow, apa, config) and + inner = ret.getEnclosingCallable() and + cc = getCallContextReturn(inner, call, innercc) and + if allowsFieldFlow = false then ap instanceof ApNil else any() + ) or - exists(DataFlowCall call, Ap argAp0 | - fwdFlowOutFromArg(call, node, state, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + // flow through a callable + exists( + DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa + | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate fwdFlowStore( - NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, ApOption argAp, - Configuration config + NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config ) { - exists(DataFlowType contentType | - fwdFlow(node1, state, cc, argAp, ap1, config) and - PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and + exists(DataFlowType contentType, ApApprox apa1 | + fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and + PrevStage::storeStepCand(node1, apa1, tc, node2, contentType, config) and typecheckStore(ap1, contentType) ) } @@ -1360,60 +1465,85 @@ private module MkStage { pragma[nomagic] private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) { exists(TypedContent tc | - fwdFlowStore(_, tail, tc, _, _, _, _, config) and + fwdFlowStore(_, tail, tc, _, _, _, _, _, config) and tc.getContent() = c and cons = apCons(tc, tail) ) } + private class ApNonNil instanceof Ap { + pragma[nomagic] + ApNonNil() { not this instanceof ApNil } + + string toString() { result = "" } + } + pragma[nomagic] - private predicate fwdFlowRead( - Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, ApOption argAp, + private predicate fwdFlowRead0( + NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap, Configuration config ) { - fwdFlow(node1, state, cc, argAp, ap, config) and + fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and + PrevStage::readStepCand(node1, _, _, config) + } + + pragma[nomagic] + private predicate fwdFlowRead( + Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, + ParamNodeOption summaryCtx, ApOption argAp, Configuration config + ) { + fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and PrevStage::readStepCand(node1, c, node2, config) and getHeadContent(ap) = c } pragma[nomagic] private predicate fwdFlowIn( - DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, Cc innercc, ApOption argAp, - Ap ap, Configuration config + DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, + ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config ) { exists(ArgNodeEx arg, boolean allowsFieldFlow | - fwdFlow(arg, state, outercc, argAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate fwdFlowOutNotFromArg( - NodeEx out, FlowState state, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowRetFromArg( + RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa, + Ap ap, ApApprox apa, Configuration config ) { - exists( - DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow, CcNoCall innercc, - DataFlowCallable inner - | - fwdFlow(ret, state, innercc, argAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and - inner = ret.getEnclosingCallable() and - ccOut = getCallContextReturn(inner, call, innercc) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(ReturnKindExt kind | + fwdFlow(pragma[only_bind_into](ret), state, ccc, + TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), + pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa), + pragma[only_bind_into](config)) and + kind = ret.getKind() and + parameterFlowThroughAllowed(summaryCtx, kind) and + argApa = getApprox(argAp) and + PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config)) ) } - pragma[nomagic] - private predicate fwdFlowOutFromArg( - DataFlowCall call, NodeEx out, FlowState state, Ap argAp, Ap ap, Configuration config + pragma[inline] + private predicate fwdFlowThrough0( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx, + Ap innerArgAp, ApApprox innerArgApa, Configuration config ) { - exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc | - fwdFlow(ret, state, ccc, apSome(argAp), ap, config) and - flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and + fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config) + } + + pragma[nomagic] + private predicate fwdFlowThrough( + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, + ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa, + config) } /** @@ -1422,11 +1552,14 @@ private module MkStage { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config + DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp, + ParamNodeEx p, Ap ap, Configuration config ) { - exists(ParamNodeEx p | - fwdFlowIn(call, p, _, cc, _, argAp, ap, config) and - PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config) + exists(ApApprox apa | + fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap, + pragma[only_bind_into](apa), pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, apa, config) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) ) } @@ -1434,146 +1567,194 @@ private module MkStage { private predicate storeStepFwd( NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2, Configuration config ) { - fwdFlowStore(node1, ap1, tc, node2, _, _, _, config) and + fwdFlowStore(node1, ap1, tc, node2, _, _, _, _, config) and ap2 = apCons(tc, ap1) and - fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, config) + fwdFlowRead(ap2, tc.getContent(), _, _, _, _, _, _, config) } private predicate readStepFwd( NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2, Configuration config ) { - fwdFlowRead(ap1, c, n1, n2, _, _, _, config) and + fwdFlowRead(ap1, c, n1, n2, _, _, _, _, config) and fwdFlowConsCand(ap1, c, ap2, config) } pragma[nomagic] - private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, NodeEx out, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(out, state, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, - pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, out, state, argAp0, ap, config) and - fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), - pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), - pragma[only_bind_into](config)) + private predicate returnFlowsThrough0( + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, + ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config + ) { + fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp, + innerArgApa, config) + } + + pragma[nomagic] + private predicate returnFlowsThrough( + RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp, + Ap ap, Configuration config + ) { + exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa | + returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and + pos = ret.getReturnPosition() and + if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap, + Configuration config ) { - flowIntoCall(call, arg, p, allowsFieldFlow, config) and - fwdFlow(arg, _, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and - callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + exists(ApApprox argApa | + flowIntoCallApa(call, pragma[only_bind_into](arg), pragma[only_bind_into](p), + allowsFieldFlow, argApa, pragma[only_bind_into](config)) and + fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa, + pragma[only_bind_into](config)) and + returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and + if allowsFieldFlow = false then argAp instanceof ApNil else any() + ) } pragma[nomagic] - private predicate returnNodeMayFlowThrough( - RetNodeEx ret, FlowState state, Ap ap, Configuration config + private predicate flowIntoCallAp( + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap ap, + Configuration config ) { - fwdFlow(ret, state, any(CcCall ccc), apSome(_), ap, config) + exists(ApApprox apa | + flowIntoCallApa(call, arg, p, allowsFieldFlow, apa, config) and + fwdFlow(arg, _, _, _, _, ap, apa, config) + ) + } + + pragma[nomagic] + private predicate flowOutOfCallAp( + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow, + Ap ap, Configuration config + ) { + exists(ApApprox apa | + flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and + fwdFlow(ret, _, _, _, _, ap, apa, config) and + pos = ret.getReturnPosition() + ) } /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. * - * The Boolean `toReturn` records whether the node must be returned from the - * enclosing callable in order to reach a sink, and if so, `returnAp` records - * the access path of the returned value. + * The parameter `returnCtx` records whether (and how) the node must be returned + * from the enclosing callable in order to reach a sink, and if so, `returnAp` + * records the access path of the returned value. */ pragma[nomagic] additional predicate revFlow( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - revFlow0(node, state, toReturn, returnAp, ap, config) and - fwdFlow(node, state, _, _, ap, config) + revFlow0(node, state, returnCtx, returnAp, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) } pragma[nomagic] private predicate revFlow0( - NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap, + Configuration config ) { - fwdFlow(node, state, _, _, ap, config) and + fwdFlow(node, state, _, _, _, ap, config) and sinkNode(node, state, config) and - (if hasSinkCallCtx(config) then toReturn = true else toReturn = false) and + ( + if hasSinkCallCtx(config) + then returnCtx = TReturnCtxNoFlowThrough() + else returnCtx = TReturnCtxNone() + ) and returnAp = apNone() and ap instanceof ApNil or exists(NodeEx mid, FlowState state0 | localStep(node, state, mid, state0, true, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, ap, config) + revFlow(mid, state0, returnCtx, returnAp, ap, config) ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, pragma[only_bind_into](state), _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, pragma[only_bind_into](state), _, _, _, ap, pragma[only_bind_into](config)) and localStep(node, pragma[only_bind_into](state), mid, state0, false, _, config, _) and - revFlow(mid, state0, toReturn, returnAp, nil, pragma[only_bind_into](config)) and + revFlow(mid, state0, returnCtx, returnAp, nil, pragma[only_bind_into](config)) and ap instanceof ApNil ) or exists(NodeEx mid | jumpStep(node, mid, config) and revFlow(mid, state, _, _, ap, config) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() ) or exists(NodeEx mid, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStep(node, mid, config) and revFlow(pragma[only_bind_into](mid), state, _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0, ApNil nil | - fwdFlow(node, _, _, _, ap, pragma[only_bind_into](config)) and + fwdFlow(node, _, _, _, _, ap, pragma[only_bind_into](config)) and additionalJumpStateStep(node, state, mid, state0, config) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, nil, pragma[only_bind_into](config)) and - toReturn = false and + returnCtx = TReturnCtxNone() and returnAp = apNone() and ap instanceof ApNil ) or // store exists(Ap ap0, Content c | - revFlowStore(ap0, c, ap, node, state, _, _, toReturn, returnAp, config) and + revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp, config) and revFlowConsCand(ap0, c, ap, config) ) or // read exists(NodeEx mid, Ap ap0 | - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and readStepFwd(node, ap, _, mid, ap0, config) ) or // flow into a callable - revFlowInNotToReturn(node, state, returnAp, ap, config) and - toReturn = false + exists(ParamNodeEx p, boolean allowsFieldFlow | + revFlow(p, state, TReturnCtxNone(), returnAp, ap, config) and + flowIntoCallAp(_, node, p, allowsFieldFlow, ap, config) and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + returnCtx = TReturnCtxNone() + ) or - exists(DataFlowCall call, Ap returnAp0 | - revFlowInToReturn(call, node, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + // flow through a callable + exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config) ) or // flow out of a callable - revFlowOut(_, node, state, _, _, ap, config) and - toReturn = true and - if returnNodeMayFlowThrough(node, state, ap, config) - then returnAp = apSome(ap) - else returnAp = apNone() + exists(ReturnPosition pos | + revFlowOut(_, node, pos, state, _, _, ap, config) and + if returnFlowsThrough(node, pos, state, _, _, _, ap, config) + then ( + returnCtx = TReturnCtxMaybeFlowThrough(pos) and + returnAp = apSome(ap) + ) else ( + returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() + ) + ) } pragma[nomagic] private predicate revFlowStore( Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid, - boolean toReturn, ApOption returnAp, Configuration config + ReturnCtx returnCtx, ApOption returnAp, Configuration config ) { - revFlow(mid, state, toReturn, returnAp, ap0, config) and + revFlow(mid, state, returnCtx, returnAp, ap0, config) and storeStepFwd(node, ap, tc, mid, ap0, config) and tc.getContent() = c } @@ -1593,36 +1774,33 @@ private module MkStage { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNodeEx ret, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, - Configuration config + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, + ApOption returnAp, Ap ap, Configuration config ) { exists(NodeEx out, boolean allowsFieldFlow | - revFlow(out, state, toReturn, returnAp, ap, config) and - flowOutOfCall(call, ret, out, allowsFieldFlow, config) and + revFlow(out, state, returnCtx, returnAp, ap, config) and + flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } pragma[nomagic] - private predicate revFlowInNotToReturn( - ArgNodeEx arg, FlowState state, ApOption returnAp, Ap ap, Configuration config + private predicate revFlowParamToReturn( + ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, false, returnAp, ap, config) and - flowIntoCall(_, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), + pragma[only_bind_into](ap), pragma[only_bind_into](config)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, getApprox(ap), config) } pragma[nomagic] - private predicate revFlowInToReturn( - DataFlowCall call, ArgNodeEx arg, FlowState state, Ap returnAp, Ap ap, Configuration config + private predicate revFlowThrough( + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, + ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config ) { - exists(ParamNodeEx p, boolean allowsFieldFlow | - revFlow(p, state, true, apSome(returnAp), ap, config) and - flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and - if allowsFieldFlow = false then ap instanceof ApNil else any() - ) + revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and + revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config) } /** @@ -1632,11 +1810,12 @@ private module MkStage { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, boolean toReturn, ApOption returnAp, Ap ap, Configuration config + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap, + Configuration config ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | - revFlowOut(call, ret, state, toReturn, returnAp, ap, config) and - fwdFlow(ret, state, ccc, apSome(_), ap, config) and + revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and + returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and matchesCall(ccc, call) ) } @@ -1673,6 +1852,11 @@ private module MkStage { pragma[nomagic] predicate revFlow(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) } + pragma[nomagic] + predicate revFlowAp(NodeEx node, Ap ap, Configuration config) { + revFlow(node, _, _, _, ap, config) + } + // use an alias as a workaround for bad functionality-induced joins pragma[nomagic] additional predicate revFlowAlias(NodeEx node, Configuration config) { @@ -1707,40 +1891,49 @@ private module MkStage { validAp(ap, config) } - pragma[noinline] - private predicate parameterFlow( - ParamNodeEx p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config + pragma[nomagic] + private predicate parameterFlowsThroughRev( + ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config ) { - revFlow(p, _, true, apSome(ap0), ap, config) and - c = p.getEnclosingCallable() + revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and + parameterFlowThroughAllowed(p, pos.getKind()) } - predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) { - exists(RetNodeEx ret, FlowState state, Ap ap0, ReturnKindExt kind, ParameterPosition pos | - parameterFlow(p, ap, ap0, c, config) and - c = ret.getEnclosingCallable() and - revFlow(pragma[only_bind_into](ret), pragma[only_bind_into](state), true, apSome(_), - pragma[only_bind_into](ap0), pragma[only_bind_into](config)) and - fwdFlow(ret, state, any(CcCall ccc), apSome(ap), ap0, config) and - kind = ret.getKind() and - p.getPosition() = pos and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - p.allowParameterReturnInSelf() - ) + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) { + exists(RetNodeEx ret, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and + parameterFlowsThroughRev(p, ap, pos, _, config) + ) + } + + pragma[nomagic] + predicate returnMayFlowThrough( + RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos | + returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and + parameterFlowsThroughRev(p, argAp, pos, ap, config) and + kind = pos.getKind() + ) + } + + pragma[nomagic] + private predicate revFlowThroughArg( + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap, Configuration config + ) { + exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp | + revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and + flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config) ) } pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists( - Ap returnAp0, ArgNodeEx arg, FlowState state, boolean toReturn, ApOption returnAp, Ap ap - | - revFlow(arg, state, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, arg, state, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | + revFlow(arg, state, returnCtx, returnAp, ap, config) and + revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config) ) } @@ -1748,13 +1941,13 @@ private module MkStage { boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, config)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, config)) and fields = count(TypedContent f0 | fwdConsCand(f0, _, config)) and conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, config)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ApOption argAp, Ap ap | - fwdFlow(n, state, cc, argAp, ap, config) + count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap | + fwdFlow(n, state, cc, summaryCtx, argAp, ap, config) ) or fwd = false and @@ -1763,8 +1956,8 @@ private module MkStage { conscand = count(TypedContent f0, Ap ap | consCand(f0, ap, config)) and states = count(FlowState state | revFlow(_, state, _, _, _, config)) and tuples = - count(NodeEx n, FlowState state, boolean b, ApOption retAp, Ap ap | - revFlow(n, state, b, retAp, ap, config) + count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap | + revFlow(n, state, returnCtx, retAp, ap, config) ) } /* End: Stage logic. */ @@ -1909,7 +2102,7 @@ private module Stage2Param implements MkStage::StageParam { exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand1/5; + predicate flowOutOfCall = flowOutOfCallNodeCand1/6; predicate flowIntoCall = flowIntoCallNodeCand1/5; @@ -1945,9 +2138,10 @@ private module Stage2 implements StageSig { pragma[nomagic] private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { - flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow, config) and Stage2::revFlow(node2, pragma[only_bind_into](config)) and Stage2::revFlowAlias(node1, pragma[only_bind_into](config)) } @@ -2015,8 +2209,8 @@ private module LocalFlowBigStep { exists(NodeEx next | Stage2::revFlow(next, state, config) | jumpStep(node, next, config) or additionalJumpStep(node, next, config) or - flowIntoCallNodeCand1(_, node, next, config) or - flowOutOfCallNodeCand1(_, node, next, config) or + flowIntoCallNodeCand2(_, node, next, _, config) or + flowOutOfCallNodeCand2(_, node, _, next, _, config) or Stage2::storeStepCand(node, _, _, next, _, config) or Stage2::readStepCand(node, _, next, config) ) @@ -2103,16 +2297,16 @@ private module LocalFlowBigStep { pragma[nomagic] predicate localFlowBigStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - AccessPathFrontNil apf, Configuration config, LocalCallContext callContext + DataFlowType t, Configuration config, LocalCallContext callContext ) { - localFlowStepPlus(node1, state1, node2, preservesValue, apf.getType(), config, callContext) and + localFlowStepPlus(node1, state1, node2, preservesValue, t, config, callContext) and localFlowExit(node2, state1, config) and state1 = state2 or additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, config) and state1 != state2 and preservesValue = false and - apf = TFrontNil(node2.getDataFlowType()) and + t = node2.getDataFlowType() and callContext.relevantFor(node1.getEnclosingCallable()) and not exists(DataFlowCall call | call = callContext.(LocalCallContextSpecificCall).getCall() | isUnreachableInCallCached(node1.asNode(), call) or @@ -2126,11 +2320,87 @@ private import LocalFlowBigStep private module Stage3Param implements MkStage::StageParam { private module PrevStage = Stage2; + class Ap = ApproxAccessPathFront; + + class ApNil = ApproxAccessPathFrontNil; + + PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + + ApNil getApNil(NodeEx node) { + PrevStage::revFlow(node, _) and result = TApproxFrontNil(node.getDataFlowType()) + } + + bindingset[tc, tail] + Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) } + + pragma[noinline] + Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() } + + class ApOption = ApproxAccessPathFrontOption; + + ApOption apNone() { result = TApproxAccessPathFrontNone() } + + ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) } + + import BooleanCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + ApproxAccessPathFrontNil ap, Configuration config, LocalCc lcc + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + exists(lcc) + } + + predicate flowOutOfCall = flowOutOfCallNodeCand2/6; + + predicate flowIntoCall = flowIntoCallNodeCand2/5; + + pragma[nomagic] + private predicate expectsContentCand(NodeEx node, Ap ap, Configuration config) { + exists(Content c | + PrevStage::revFlow(node, pragma[only_bind_into](config)) and + PrevStage::readStepCand(_, c, _, pragma[only_bind_into](config)) and + expectsContentEx(node, c) and + c = ap.getAHead().getContent() + ) + } + + pragma[nomagic] + private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode } + + bindingset[node, state, ap, config] + predicate filter(NodeEx node, FlowState state, Ap ap, Configuration config) { + exists(state) and + exists(config) and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), ap.getType()) else any()) and + ( + notExpectsContent(node) + or + expectsContentCand(node, ap, config) + ) + } + + bindingset[ap, contentType] + predicate typecheckStore(Ap ap, DataFlowType contentType) { + // We need to typecheck stores here, since reverse flow through a getter + // might have a different type here compared to inside the getter. + compatibleTypes(ap.getType(), contentType) + } +} + +private module Stage3 implements StageSig { + import MkStage::Stage +} + +private module Stage4Param implements MkStage::StageParam { + private module PrevStage = Stage3; + class Ap = AccessPathFront; class ApNil = AccessPathFrontNil; - PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } + PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } ApNil getApNil(NodeEx node) { PrevStage::revFlow(node, _) and result = TFrontNil(node.getDataFlowType()) @@ -2150,16 +2420,42 @@ private module Stage3Param implements MkStage::StageParam { import BooleanCallContext + pragma[nomagic] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap, config, _) and exists(lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, _) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) and + exists(lcc) } - predicate flowOutOfCall = flowOutOfCallNodeCand2/5; + pragma[nomagic] + predicate flowOutOfCall( + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } - predicate flowIntoCall = flowIntoCallNodeCand2/5; + pragma[nomagic] + predicate flowIntoCall( + DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow, + Configuration config + ) { + exists(FlowState state | + flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, + pragma[only_bind_into](config)) + ) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c, Configuration config) { @@ -2215,8 +2511,8 @@ private module Stage3Param implements MkStage::StageParam { } } -private module Stage3 implements StageSig { - import MkStage::Stage +private module Stage4 implements StageSig { + import MkStage::Stage } /** @@ -2227,8 +2523,9 @@ private predicate flowCandSummaryCtx( NodeEx node, FlowState state, AccessPathFront argApf, Configuration config ) { exists(AccessPathFront apf | - Stage3::revFlow(node, state, true, _, apf, config) and - Stage3::fwdFlow(node, state, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) + Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf, config) and + Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, TAccessPathFrontSome(argApf), apf, + config) ) } @@ -2238,10 +2535,10 @@ private predicate flowCandSummaryCtx( */ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) { exists(int tails, int nodes, int apLimit, int tupleLimit | - tails = strictcount(AccessPathFront apf | Stage3::consCand(tc, apf, config)) and + tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf, config)) and nodes = strictcount(NodeEx n, FlowState state | - Stage3::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) + Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) or flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc), config) ) and @@ -2255,11 +2552,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) private newtype TAccessPathApprox = TNil(DataFlowType t) or TConsNil(TypedContent tc, DataFlowType t) { - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and not expensiveLen2unfolding(tc, _) } or TConsCons(TypedContent tc1, TypedContent tc2, int len) { - Stage3::consCand(tc1, TFrontHead(tc2), _) and + Stage4::consCand(tc1, TFrontHead(tc2), _) and len in [2 .. accessPathLimit()] and not expensiveLen2unfolding(tc1, _) } or @@ -2389,7 +2686,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { override AccessPathApprox pop(TypedContent head) { head = tc and ( - exists(TypedContent tc2 | Stage3::consCand(tc, TFrontHead(tc2), _) | + exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2), _) | result = TConsCons(tc2, _, len - 1) or len = 2 and @@ -2400,7 +2697,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 { or exists(DataFlowType t | len = 1 and - Stage3::consCand(tc, TFrontNil(t), _) and + Stage4::consCand(tc, TFrontNil(t), _) and result = TNil(t) ) ) @@ -2425,13 +2722,14 @@ private class AccessPathApproxOption extends TAccessPathApproxOption { } } -private module Stage4Param implements MkStage::StageParam { - private module PrevStage = Stage3; +private module Stage5Param implements MkStage::StageParam { + private module PrevStage = Stage4; class Ap = AccessPathApprox; class ApNil = AccessPathApproxNil; + pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } ApNil getApNil(NodeEx node) { @@ -2457,15 +2755,18 @@ private module Stage4Param implements MkStage::StageParam { NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, ApNil ap, Configuration config, LocalCc lcc ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getFront(), config, lcc) + localFlowBigStep(node1, state1, node2, state2, preservesValue, ap.getType(), config, lcc) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _, pragma[only_bind_into](config)) and + PrevStage::revFlowAlias(node2, pragma[only_bind_into](state2), _, pragma[only_bind_into](config)) } pragma[nomagic] predicate flowOutOfCall( - DataFlowCall call, RetNodeEx node1, NodeEx node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow, + Configuration config ) { exists(FlowState state | - flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and + flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow, config) and PrevStage::revFlow(node2, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) and PrevStage::revFlowAlias(node1, pragma[only_bind_into](state), _, pragma[only_bind_into](config)) @@ -2493,7 +2794,7 @@ private module Stage4Param implements MkStage::StageParam { predicate typecheckStore(Ap ap, DataFlowType contentType) { any() } } -private module Stage4 = MkStage::Stage; +private module Stage5 = MkStage::Stage; bindingset[conf, result] private Configuration unbindConf(Configuration conf) { @@ -2502,13 +2803,13 @@ private Configuration unbindConf(Configuration conf) { pragma[nomagic] private predicate nodeMayUseSummary0( - NodeEx n, DataFlowCallable c, FlowState state, AccessPathApprox apa, Configuration config + NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config ) { exists(AccessPathApprox apa0 | - Stage4::parameterMayFlowThrough(_, c, _, _) and - Stage4::revFlow(n, state, true, _, apa0, config) and - Stage4::fwdFlow(n, state, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and - n.getEnclosingCallable() = c + Stage5::parameterMayFlowThrough(p, _, _) and + Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and + Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), + TAccessPathApproxSome(apa), apa0, config) ) } @@ -2516,9 +2817,9 @@ pragma[nomagic] private predicate nodeMayUseSummary( NodeEx n, FlowState state, AccessPathApprox apa, Configuration config ) { - exists(DataFlowCallable c | - Stage4::parameterMayFlowThrough(_, c, apa, config) and - nodeMayUseSummary0(n, c, state, apa, config) + exists(ParamNodeEx p | + Stage5::parameterMayFlowThrough(p, apa, config) and + nodeMayUseSummary0(n, p, state, apa, config) ) } @@ -2526,8 +2827,8 @@ private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, AccessPath ap) { exists(Configuration config | - Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), config) and - Stage4::revFlow(p, state, _, config) + Stage5::parameterMayFlowThrough(p, ap.getApprox(), config) and + Stage5::revFlow(p, state, _, config) ) } @@ -2576,7 +2877,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { len = apa.len() and result = strictcount(AccessPathFront apf | - Stage4::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), + Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1), config) ) ) @@ -2585,7 +2886,7 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) { private int countNodesUsingAccessPath(AccessPathApprox apa, Configuration config) { result = strictcount(NodeEx n, FlowState state | - Stage4::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) + Stage5::revFlow(n, state, apa, config) or nodeMayUseSummary(n, state, apa, config) ) } @@ -2606,7 +2907,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { exists(TypedContent head | apa.pop(head) = result and - Stage4::consCand(head, result, config) + Stage5::consCand(head, result, config) ) } @@ -2688,7 +2989,7 @@ private newtype TPathNode = NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config ) { // A PathNode is introduced by a source ... - Stage4::revFlow(node, state, config) and + Stage5::revFlow(node, state, config) and sourceNode(node, state, config) and ( if hasSourceCallCtx(config) @@ -2702,7 +3003,7 @@ private newtype TPathNode = exists(PathNodeMid mid | pathStep(mid, node, state, cc, sc, ap) and pragma[only_bind_into](config) = mid.getConfiguration() and - Stage4::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) + Stage5::revFlow(node, state, ap.getApprox(), pragma[only_bind_into](config)) ) } or TPathNodeSink(NodeEx node, FlowState state, Configuration config) { @@ -2712,6 +3013,18 @@ private newtype TPathNode = state = sink.getState() and config = sink.getConfiguration() ) + } or + TPathNodeSourceGroup(string sourceGroup, Configuration config) { + exists(PathNodeImpl source | + sourceGroup = source.getSourceGroup() and + config = source.getConfiguration() + ) + } or + TPathNodeSinkGroup(string sinkGroup, Configuration config) { + exists(PathNodeSink sink | + sinkGroup = sink.getSinkGroup() and + config = sink.getConfiguration() + ) } /** @@ -2832,7 +3145,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 { override TypedContent getHead() { result = head1 } override AccessPath getTail() { - Stage4::consCand(head1, result.getApprox(), _) and + Stage5::consCand(head1, result.getApprox(), _) and result.getHead() = head2 and result.length() = len - 1 } @@ -2863,7 +3176,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 { override TypedContent getHead() { result = head } override AccessPath getTail() { - Stage4::consCand(head, result.getApprox(), _) and result.length() = len - 1 + Stage5::consCand(head, result.getApprox(), _) and result.length() = len - 1 } override AccessPathFrontHead getFront() { result = TFrontHead(head) } @@ -2920,6 +3233,22 @@ abstract private class PathNodeImpl extends TPathNode { ) } + string getSourceGroup() { + this.isSource() and + this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result) + } + + predicate isFlowSource() { + this.isSource() and not exists(this.getSourceGroup()) + or + this instanceof PathNodeSourceGroup + } + + predicate isFlowSink() { + this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or + this instanceof PathNodeSinkGroup + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -2959,7 +3288,9 @@ abstract private class PathNodeImpl extends TPathNode { /** Holds if `n` can reach a sink. */ private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) + n instanceof PathNodeSink or + n instanceof PathNodeSinkGroup or + directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ @@ -3015,6 +3346,12 @@ class PathNode instanceof PathNodeImpl { /** Holds if this node is a source. */ final predicate isSource() { super.isSource() } + + /** Holds if this node is a grouping of source nodes. */ + final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) } + + /** Holds if this node is a grouping of sink nodes. */ + final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) } } /** @@ -3136,9 +3473,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNodeImpl getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { + result = TPathNodeSinkGroup(this.getSinkGroup(), config) + } override predicate isSource() { sourceNode(node, state, config) } + + string getSinkGroup() { config.sinkGrouping(node.asNode(), result) } +} + +private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup { + string sourceGroup; + Configuration config; + + PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { + result.getSourceGroup() = sourceGroup and + result.getConfiguration() = config + } + + override predicate isSource() { none() } + + override string toString() { result = sourceGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } +} + +private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup { + string sinkGroup; + Configuration config; + + PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) } + + override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } + + override Configuration getConfiguration() { result = config } + + override PathNodeImpl getASuccessorImpl() { none() } + + override predicate isSource() { none() } + + override string toString() { result = sinkGroup } + + override predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 + } } private predicate pathNode( @@ -3174,7 +3568,8 @@ private predicate pathStep( AccessPath ap0, NodeEx midnode, FlowState state0, Configuration conf, LocalCallContext localCC | pathNode(mid, midnode, state0, cc, sc, ap0, conf, localCC) and - localFlowBigStep(midnode, state0, node, state, false, ap.getFront(), conf, localCC) and + localFlowBigStep(midnode, state0, node, state, false, ap.(AccessPathNil).getType(), conf, + localCC) and ap0 instanceof AccessPathNil ) or @@ -3216,7 +3611,7 @@ private predicate pathReadStep( ) { ap0 = mid.getAp() and tc = ap0.getHead() and - Stage4::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and + Stage5::readStepCand(mid.getNodeEx(), tc.getContent(), node, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3226,7 +3621,7 @@ private predicate pathStoreStep( PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, TypedContent tc, CallContext cc ) { ap0 = mid.getAp() and - Stage4::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and + Stage5::storeStepCand(mid.getNodeEx(), _, tc, node, _, mid.getConfiguration()) and state = mid.getState() and cc = mid.getCallContext() } @@ -3263,7 +3658,7 @@ private NodeEx getAnOutNodeFlow( ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa, Configuration config ) { result.asNode() = kind.getAnOutNode(call) and - Stage4::revFlow(result, _, apa, config) + Stage5::revFlow(result, _, apa, config) } /** @@ -3299,7 +3694,7 @@ private predicate parameterCand( DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config ) { exists(ParamNodeEx p | - Stage4::revFlow(p, _, apa, config) and + Stage5::revFlow(p, _, apa, config) and p.isParameterOf(callable, pos) ) } @@ -3354,17 +3749,11 @@ private predicate paramFlowsThrough( ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa, Configuration config ) { - exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos | + exists(PathNodeMid mid, RetNodeEx ret | pathNode(mid, ret, state, cc, sc, ap, config, _) and kind = ret.getKind() and apa = ap.getApprox() and - pos = sc.getParameterPos() and - // we don't expect a parameter to return stored in itself, unless explicitly allowed - ( - not kind.(ParamUpdateReturnKind).getPosition() = pos - or - sc.getParamNode().allowParameterReturnInSelf() - ) + parameterFlowThroughAllowed(sc.getParamNode(), kind) ) } @@ -3495,6 +3884,15 @@ private module Subpaths { * Will only have results if `configuration` has non-empty sources and * sinks. */ +private predicate hasFlowPath( + PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration +) { + flowsource.isFlowSource() and + flowsource.getConfiguration() = configuration and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isFlowSink() +} + private predicate flowsTo( PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration @@ -3575,9 +3973,17 @@ predicate stageStats( n = 45 and Stage4::stats(false, nodes, fields, conscand, states, tuples, config) or - stage = "5 Fwd" and n = 50 and finalStats(true, nodes, fields, conscand, states, tuples) + stage = "5 Fwd" and + n = 50 and + Stage5::stats(true, nodes, fields, conscand, states, tuples, config) or - stage = "5 Rev" and n = 55 and finalStats(false, nodes, fields, conscand, states, tuples) + stage = "5 Rev" and + n = 55 and + Stage5::stats(false, nodes, fields, conscand, states, tuples, config) + or + stage = "6 Fwd" and n = 60 and finalStats(true, nodes, fields, conscand, states, tuples) + or + stage = "6 Rev" and n = 65 and finalStats(false, nodes, fields, conscand, states, tuples) } private module FlowExploration { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll index 2ad6f844492..87ee04c1096 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll @@ -1,49 +1,77 @@ private import java private import semmle.code.java.dataflow.InstanceAccess +private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSummary private import semmle.code.java.dataflow.TypeFlow private import DataFlowPrivate +private import DataFlowUtil private import FlowSummaryImpl as FlowSummaryImpl private import DataFlowImplCommon as DataFlowImplCommon +/** Gets a string for approximating the name of a field. */ +string approximateFieldContent(FieldContent fc) { result = fc.getField().getName().prefix(1) } + cached -newtype TNode = - TExprNode(Expr e) { - DataFlowImplCommon::forceCachingInSameStage() and - not e.getType() instanceof VoidType and - not e.getParent*() instanceof Annotation - } or - TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or - TImplicitVarargsArray(Call c) { - c.getCallee().isVarargs() and - not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray()) - } or - TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or - TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or - TMallocNode(ClassInstanceExpr cie) or - TExplicitExprPostUpdate(Expr e) { - explicitInstanceArgument(_, e) - or - e instanceof Argument and not e.getType() instanceof ImmutableType - or - exists(FieldAccess fa | fa.getField() instanceof InstanceField and e = fa.getQualifier()) - or - exists(ArrayAccess aa | e = aa.getArray()) - } or - TImplicitExprPostUpdate(InstanceAccessExt ia) { - implicitInstanceArgument(_, ia) - or - exists(FieldAccess fa | - fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa) - ) - } or - TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(SummarizedCallable c, int pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or - TFieldValueNode(Field f) +private module Cached { + cached + newtype TNode = + TExprNode(Expr e) { + DataFlowImplCommon::forceCachingInSameStage() and + not e.getType() instanceof VoidType and + not e.getParent*() instanceof Annotation + } or + TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or + TImplicitVarargsArray(Call c) { + c.getCallee().isVarargs() and + not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray()) + } or + TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or + TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or + TMallocNode(ClassInstanceExpr cie) or + TExplicitExprPostUpdate(Expr e) { + explicitInstanceArgument(_, e) + or + e instanceof Argument and not e.getType() instanceof ImmutableType + or + exists(FieldAccess fa | fa.getField() instanceof InstanceField and e = fa.getQualifier()) + or + exists(ArrayAccess aa | e = aa.getArray()) + } or + TImplicitExprPostUpdate(InstanceAccessExt ia) { + implicitInstanceArgument(_, ia) + or + exists(FieldAccess fa | + fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa) + ) + } or + TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { + FlowSummaryImpl::Private::summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, int pos) { + FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) + } or + TFieldValueNode(Field f) + + cached + newtype TContent = + TFieldContent(InstanceField f) or + TArrayContent() or + TCollectionContent() or + TMapKeyContent() or + TMapValueContent() or + TSyntheticFieldContent(SyntheticField s) + + cached + newtype TContentApprox = + TFieldContentApprox(string firstChar) { firstChar = approximateFieldContent(_) } or + TArrayContentApprox() or + TCollectionContentApprox() or + TMapKeyContentApprox() or + TMapValueContentApprox() or + TSyntheticFieldApproxContent() +} + +import Cached private predicate explicitInstanceArgument(Call call, Expr instarg) { call instanceof MethodAccess and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 6888899079c..ef89d0f51a2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -9,6 +9,7 @@ private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.dataflow.FlowSummary private import FlowSummaryImpl as FlowSummaryImpl private import DataFlowImplConsistency +private import DataFlowNodes import DataFlowNodes::Private private newtype TReturnKind = TNormalReturnKind() @@ -420,6 +421,48 @@ predicate allowParameterReturnInSelf(ParameterNode p) { FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p) } +/** An approximated `Content`. */ +class ContentApprox extends TContentApprox { + /** Gets a textual representation of this approximated `Content`. */ + string toString() { + exists(string firstChar | + this = TFieldContentApprox(firstChar) and + result = "approximated field " + firstChar + ) + or + this = TArrayContentApprox() and + result = "[]" + or + this = TCollectionContentApprox() and + result = "" + or + this = TMapKeyContentApprox() and + result = "" + or + this = TMapValueContentApprox() and + result = "" + or + this = TSyntheticFieldApproxContent() and + result = "approximated synthetic field" + } +} + +/** Gets an approximated value for content `c`. */ +pragma[nomagic] +ContentApprox getContentApprox(Content c) { + result = TFieldContentApprox(approximateFieldContent(c)) + or + c instanceof ArrayContent and result = TArrayContentApprox() + or + c instanceof CollectionContent and result = TCollectionContentApprox() + or + c instanceof MapKeyContent and result = TMapKeyContentApprox() + or + c instanceof MapValueContent and result = TMapValueContentApprox() + or + c instanceof SyntheticFieldContent and result = TSyntheticFieldApproxContent() +} + private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { override predicate argHasPostUpdateExclude(ArgumentNode n) { n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 4cd63b152f6..ba5a1cfacc7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -12,6 +12,7 @@ private import semmle.code.java.dataflow.FlowSummary private import semmle.code.java.dataflow.InstanceAccess private import FlowSummaryImpl as FlowSummaryImpl private import TaintTrackingUtil as TaintTrackingUtil +private import DataFlowNodes import DataFlowNodes::Public import semmle.code.Unit @@ -186,14 +187,6 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) { FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true) } -private newtype TContent = - TFieldContent(InstanceField f) or - TArrayContent() or - TCollectionContent() or - TMapKeyContent() or - TMapValueContent() or - TSyntheticFieldContent(SyntheticField s) - /** * A description of the way data may be stored inside an object. Examples * include instance fields, the contents of a collection object, or the contents diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 4d41254e5e9..b61142c33a7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -241,19 +241,25 @@ module Public { } /** - * Holds if the summary is auto generated. + * Holds if the summary is auto generated and not manually generated. */ predicate isAutoGenerated() { none() } - } - - /** A callable with a flow summary stating there is no flow via the callable. */ - class NegativeSummarizedCallable extends SummarizedCallableBase { - NegativeSummarizedCallable() { negativeSummaryElement(this, _) } /** - * Holds if the negative summary is auto generated. + * Holds if the summary has the given provenance where `true` is + * `generated` and `false` is `manual`. */ - predicate isAutoGenerated() { negativeSummaryElement(this, true) } + predicate hasProvenance(boolean generated) { none() } + } + + /** A callable where there is no flow via the callable. */ + class NeutralCallable extends SummarizedCallableBase { + NeutralCallable() { neutralElement(this, _) } + + /** + * Holds if the neutral is auto generated. + */ + predicate isAutoGenerated() { neutralElement(this, true) } } } @@ -520,7 +526,8 @@ module Private { predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or - isParameterPostUpdate(_, c, pos) + // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context + any(SummaryNodeState state).isOutputState(c, SummaryComponentStack::argument(pos)) } private predicate callbackOutput( @@ -1011,6 +1018,10 @@ module Private { } override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) } + + override predicate hasProvenance(boolean generated) { + summaryElement(this, _, _, _, generated) + } } /** Holds if component `c` of specification `spec` cannot be parsed. */ @@ -1160,9 +1171,9 @@ module Private { string toString() { result = super.toString() } } - /** A flow summary to include in the `negativeSummary/1` query predicate. */ - abstract class RelevantNegativeSummarizedCallable instanceof NegativeSummarizedCallable { - /** Gets the string representation of this callable used by `summary/1`. */ + /** A model to include in the `neutral/1` query predicate. */ + abstract class RelevantNeutralCallable instanceof NeutralCallable { + /** Gets the string representation of this callable used by `neutral/1`. */ abstract string getCallableCsv(); string toString() { result = super.toString() } @@ -1179,13 +1190,13 @@ module Private { if c.isAutoGenerated() then result = "generated" else result = "manual" } - private string renderProvenanceNegative(NegativeSummarizedCallable c) { + private string renderProvenanceNeutral(NeutralCallable c) { if c.isAutoGenerated() then result = "generated" else result = "manual" } /** * A query predicate for outputting flow summaries in semi-colon separated format in QL tests. - * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance"", + * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance", * ext is hardcoded to empty. */ query predicate summary(string csv) { @@ -1204,14 +1215,14 @@ module Private { } /** - * Holds if a negative flow summary `csv` exists (semi-colon separated format). Used for testing purposes. + * Holds if a neutral model `csv` exists (semi-colon separated format). Used for testing purposes. * The syntax is: "namespace;type;name;signature;provenance"", */ - query predicate negativeSummary(string csv) { - exists(RelevantNegativeSummarizedCallable c | + query predicate neutral(string csv) { + exists(RelevantNeutralCallable c | csv = c.getCallableCsv() // Callable information - + renderProvenanceNegative(c) // provenance + + renderProvenanceNeutral(c) // provenance ) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index b005bab3257..883b791835b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -14,10 +14,17 @@ private import semmle.code.java.dataflow.internal.AccessPathSyntax as AccessPath class SummarizedCallableBase = FlowSummary::SummarizedCallableBase; +/** + * A module for importing frameworks that define synthetic globals. + */ +private module SyntheticGlobals { + private import semmle.code.java.frameworks.android.Intent +} + DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c } /** Gets the parameter position of the instance parameter. */ -int instanceParameterPosition() { result = -1 } +ArgumentPosition instanceParameterPosition() { result = -1 } /** Gets the synthesized summary data-flow node for the given values. */ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) } @@ -113,8 +120,11 @@ private predicate correspondingKotlinParameterDefaultsArgSpec( exists(int oldArgParsed | oldArgParsed = AccessPathSyntax::AccessPath::parseInt(oldArgNumber.splitAt(",").trim()) | - if ktExtensionFunctions(originalCallable, _, _) and oldArgParsed = 0 - then defaultsArgSpec = "Argument[0]" + if + ktExtensionFunctions(originalCallable, _, _) and + ktExtensionFunctions(defaultsCallable, _, _) and + oldArgParsed = 0 + then defaultsArgSpec = "Argument[" + paramOffset + "]" // 1 if dispatch receiver is present, 0 otherwise. else defaultsArgSpec = "Argument[" + (oldArgParsed + paramOffset) + "]" + rest ) ) @@ -153,12 +163,12 @@ predicate summaryElement( } /** - * Holds if a negative flow summary exists for `c`, which means that there is no - * flow through `c`. The flag `generated` states whether the summary is autogenerated. + * Holds if a neutral model exists for `c`, which means that there is no + * flow through `c`. The flag `generated` states whether the model is autogenerated. */ -predicate negativeSummaryElement(SummarizedCallableBase c, boolean generated) { +predicate neutralElement(SummarizedCallableBase c, boolean generated) { exists(string namespace, string type, string name, string signature, string provenance | - negativeSummaryModel(namespace, type, name, signature, provenance) and + neutralModel(namespace, type, name, signature, provenance) and generated = isGenerated(provenance) and c.asCallable() = interpretElement(namespace, type, false, name, signature, "") ) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll b/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll deleted file mode 100644 index e7b6b7b8838..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/NegativeSummary.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** Provides modules for importing negative summaries. */ - -/** - * A module importing the frameworks that provide external flow data, - * ensuring that they are visible to the taint tracking / data flow library. - */ -private module Frameworks { - private import semmle.code.java.frameworks.GeneratedNegative -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 4ba026bd045..874c08bdaba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -10,7 +10,6 @@ private import semmle.code.java.dataflow.internal.ContainerFlow private import semmle.code.java.frameworks.spring.SpringController private import semmle.code.java.frameworks.spring.SpringHttp private import semmle.code.java.frameworks.Networking -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.internal.DataFlowPrivate import semmle.code.java.dataflow.FlowSteps diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll index 6296d255103..d20ae81b00b 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll @@ -274,7 +274,7 @@ class DeadMethod extends Callable { class RootdefCallable extends Callable { RootdefCallable() { - this.fromSource() and + this.getFile().isJavaSourceFile() and not this.(Method).overridesOrInstantiates(_) } diff --git a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll index d6d0653c1ea..81f5a2d765e 100644 --- a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll @@ -58,9 +58,7 @@ abstract class WhitelistedLiveCallable extends CallableEntryPoint { } /** * A `public static void main(String[] args)` method. */ -class MainMethodEntry extends CallableEntryPoint { - MainMethodEntry() { this instanceof MainMethod } -} +class MainMethodEntry extends CallableEntryPoint instanceof MainMethod { } /** * A method that overrides a library method -- the result is @@ -96,9 +94,7 @@ abstract class ReflectivelyConstructedClass extends EntryPoint, Class { /** * Classes that are deserialized by Jackson are reflectively constructed. */ -library class JacksonReflectivelyConstructedClass extends ReflectivelyConstructedClass { - JacksonReflectivelyConstructedClass() { this instanceof JacksonDeserializableType } - +library class JacksonReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof JacksonDeserializableType { override Callable getALiveCallable() { // Constructors may be called by Jackson, if they are a no-arg, they have a suitable annotation, // or inherit a suitable annotation through a mixin. @@ -312,8 +308,7 @@ class FacesAccessibleMethodEntryPoint extends CallableEntryPoint { * A Java Server Faces custom component, that is reflectively constructed by the framework when * used in a view (JSP or facelet). */ -class FacesComponentReflectivelyConstructedClass extends ReflectivelyConstructedClass { - FacesComponentReflectivelyConstructedClass() { this instanceof FacesComponent } +class FacesComponentReflectivelyConstructedClass extends ReflectivelyConstructedClass instanceof FacesComponent { } /** @@ -400,8 +395,7 @@ class JavaxManagedBeanReflectivelyConstructed extends ReflectivelyConstructedCla * Classes marked as Java persistence entities can be reflectively constructed when the data is * loaded. */ -class PersistentEntityEntryPoint extends ReflectivelyConstructedClass { - PersistentEntityEntryPoint() { this instanceof PersistentEntity } +class PersistentEntityEntryPoint extends ReflectivelyConstructedClass instanceof PersistentEntity { } /** @@ -465,6 +459,5 @@ class ArbitraryXmlEntryPoint extends ReflectivelyConstructedClass { deprecated class ArbitraryXMLEntryPoint = ArbitraryXmlEntryPoint; /** A Selenium PageObject, created by a call to PageFactory.initElements(..). */ -class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass { - SeleniumPageObjectEntryPoint() { this instanceof SeleniumPageObject } +class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass instanceof SeleniumPageObject { } diff --git a/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll index fd2dc8974f7..caac4d37b6c 100644 --- a/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/SpringEntryPoints.qll @@ -50,9 +50,7 @@ class SpringBeanAnnotatedMethod extends CallableEntryPoint { /** * A live entry point within a Spring controller. */ -class SpringControllerEntryPoint extends CallableEntryPoint { - SpringControllerEntryPoint() { this instanceof SpringControllerMethod } -} +class SpringControllerEntryPoint extends CallableEntryPoint instanceof SpringControllerMethod { } /** * A method that is accessible in a response, because it is part of the returned model, diff --git a/java/ql/lib/semmle/code/java/deadcode/StrutsEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/StrutsEntryPoints.qll index 3599d1fe640..de2c0c44678 100644 --- a/java/ql/lib/semmle/code/java/deadcode/StrutsEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/StrutsEntryPoints.qll @@ -33,23 +33,18 @@ class Struts1ActionEntryPoint extends EntryPoint, Class { /** * A struts 2 action class that is reflectively constructed. */ -class Struts2ReflectivelyConstructedAction extends ReflectivelyConstructedClass { - Struts2ReflectivelyConstructedAction() { this instanceof Struts2ActionClass } +class Struts2ReflectivelyConstructedAction extends ReflectivelyConstructedClass instanceof Struts2ActionClass { } /** * A method called on a struts 2 action class when the action is activated. */ -class Struts2ActionMethodEntryPoint extends CallableEntryPoint { - Struts2ActionMethodEntryPoint() { this instanceof Struts2ActionMethod } -} +class Struts2ActionMethodEntryPoint extends CallableEntryPoint instanceof Struts2ActionMethod { } /** * A method called on a struts 2 action class before an action is activated. */ -class Struts2PrepareMethodEntryPoint extends CallableEntryPoint { - Struts2PrepareMethodEntryPoint() { this instanceof Struts2PrepareMethod } -} +class Struts2PrepareMethodEntryPoint extends CallableEntryPoint instanceof Struts2PrepareMethod { } /** * A class which is accessible - directly or indirectly - from a struts action. diff --git a/java/ql/lib/semmle/code/java/deadcode/TestEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/TestEntryPoints.qll index 2d8b28e4de9..d659918e815 100644 --- a/java/ql/lib/semmle/code/java/deadcode/TestEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/TestEntryPoints.qll @@ -78,13 +78,10 @@ class JUnitCategory extends WhitelistedLiveClass { /** * A listener that will be reflectively constructed by TestNG. */ -class TestNGReflectivelyConstructedListener extends ReflectivelyConstructedClass { - TestNGReflectivelyConstructedListener() { - // Consider any class that implements a TestNG listener interface to be live. Listeners can be - // specified on the command line, in `testng.xml` files and in Ant build files, so it is safest - // to assume that all such listeners are live. - this instanceof TestNGListenerImpl - } +class TestNGReflectivelyConstructedListener extends ReflectivelyConstructedClass instanceof TestNGListenerImpl { + // Consider any class that implements a TestNG listener interface to be live. Listeners can be + // specified on the command line, in `testng.xml` files and in Ant build files, so it is safest + // to assume that all such listeners are live. } /** @@ -99,9 +96,7 @@ class TestNGDataProvidersEntryPoint extends CallableEntryPoint { /** * A `@Factory` TestNG method or constructor which is live. */ -class TestNGFactoryEntryPoint extends CallableEntryPoint { - TestNGFactoryEntryPoint() { this instanceof TestNGFactoryCallable } -} +class TestNGFactoryEntryPoint extends CallableEntryPoint instanceof TestNGFactoryCallable { } class TestRefectivelyConstructedClass extends ReflectivelyConstructedClass { TestRefectivelyConstructedClass() { @@ -159,6 +154,5 @@ class CucumberConstructedClass extends ReflectivelyConstructedClass { /** * A "step definition" that may be called by Cucumber when executing an acceptance test. */ -class CucumberStepDefinitionEntryPoint extends CallableEntryPoint { - CucumberStepDefinitionEntryPoint() { this instanceof CucumberStepDefinition } +class CucumberStepDefinitionEntryPoint extends CallableEntryPoint instanceof CucumberStepDefinition { } diff --git a/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll index 5f2f215802f..d25b07d1999 100644 --- a/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/WebEntryPoints.qll @@ -7,17 +7,12 @@ import semmle.code.java.frameworks.Servlets * Any class which extends the `Servlet` interface is intended to be constructed reflectively by a * servlet container. */ -class ServletConstructedClass extends ReflectivelyConstructedClass { +class ServletConstructedClass extends ReflectivelyConstructedClass instanceof ServletClass { ServletConstructedClass() { - this instanceof ServletClass and // If we have seen any `web.xml` files, this servlet will be considered to be live only if it is // referred to as a servlet-class in at least one. If no `web.xml` files are found, we assume // that XML extraction was not enabled, and therefore consider all `Servlet` classes as live. - ( - isWebXmlIncluded() - implies - exists(WebServletClass servletClass | this = servletClass.getClass()) - ) + isWebXmlIncluded() implies exists(WebServletClass servletClass | this = servletClass.getClass()) } } @@ -112,6 +107,4 @@ class GwtUiBinderEntryPoint extends CallableEntryPoint { /** * Fields that may be reflectively read or written to by the UiBinder framework. */ -class GwtUiBinderReflectivelyReadField extends ReflectivelyReadField { - GwtUiBinderReflectivelyReadField() { this instanceof GwtUiField } -} +class GwtUiBinderReflectivelyReadField extends ReflectivelyReadField instanceof GwtUiField { } diff --git a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll index 2087f076fa9..c6419f4c26b 100644 --- a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll @@ -9,11 +9,12 @@ import java private import VirtualDispatch private import semmle.code.java.dataflow.internal.BaseSSA -private import semmle.code.java.dataflow.internal.DataFlowUtil -private import semmle.code.java.dataflow.internal.DataFlowPrivate +private import semmle.code.java.dataflow.internal.DataFlowUtil as DataFlow +private import semmle.code.java.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import semmle.code.java.dataflow.InstanceAccess private import semmle.code.java.Collections private import semmle.code.java.Maps +private import codeql.typetracking.TypeTracking /** * Gets a viable dispatch target for `ma`. This is the input dispatch relation. @@ -23,7 +24,8 @@ private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v2(ma) } private Callable dispatchCand(Call c) { c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() or - result = viableImpl_inp(c) + result = viableImpl_inp(c) and + not dispatchOrigin(_, c, result) } /** @@ -56,7 +58,7 @@ private predicate publicStaticFieldInit(ClassInstanceExpr cie) { */ private predicate publicThroughField(RefType t) { exists(ClassInstanceExpr cie | - cie.getConstructedType() = t and + cie.getConstructedType().getSourceDeclaration() = t and publicStaticFieldInit(cie) ) } @@ -64,7 +66,7 @@ private predicate publicThroughField(RefType t) { /** * Holds if `t` and its subtypes are private or anonymous. */ -private predicate privateConstruction(RefType t) { +private predicate privateConstruction(SrcRefType t) { (t.isPrivate() or t instanceof AnonymousClass) and not publicThroughField(t) and forall(SrcRefType sub | sub.getASourceSupertype+() = t.getSourceDeclaration() | @@ -122,188 +124,282 @@ private predicate relevant(RefType t) { } /** A node with a type that is relevant for dispatch flow. */ -private class RelevantNode extends Node { +private class RelevantNode extends DataFlow::Node { RelevantNode() { relevant(this.getType()) } } -/** - * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. - * The instance parameter is considered to have index `-1`. - */ -pragma[nomagic] -private predicate viableParamCand(Call call, int i, ParameterNode p) { - exists(DataFlowCallable callable | - callable.asCallable() = dispatchCand(call) and - p.isParameterOf(callable, i) and - p instanceof RelevantNode - ) -} +private module TypeTrackingSteps { + class Node = RelevantNode; -/** - * Holds if `arg` is a possible argument to `p` taking virtual dispatch into account. - */ -private predicate viableArgParamCand(ArgumentNode arg, ParameterNode p) { - exists(int i, DataFlowCall call | - viableParamCand(call.asCall(), i, p) and - arg.argumentOf(call, i) - ) -} + class LocalSourceNode extends RelevantNode { + LocalSourceNode() { + this.asExpr() instanceof Call or + this.asExpr() instanceof RValue or + this instanceof DataFlow::ParameterNode or + this instanceof DataFlow::ImplicitVarargsArray or + this.asExpr() instanceof ArrayInit or + this.asExpr() instanceof ArrayAccess or + this instanceof DataFlow::FieldValueNode + } + } -/** - * Holds if data may flow from `n1` to `n2` in a single step through a call or a return. - */ -private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) { - exists(ReturnStmt ret, Method m | - ret.getEnclosingCallable() = m and - ret.getResult() = n1.asExpr() and - m = dispatchCand(n2.asExpr()) - ) - or - viableArgParamCand(n1, n2) -} + private newtype TContent = + ContentArray() or + ContentArrayArray() -/** - * Holds if data may flow from `n1` to `n2` in a single step that does not go - * through a call or a return. - */ -private predicate flowStep(RelevantNode n1, RelevantNode n2) { - exists(BaseSsaVariable v, BaseSsaVariable def | - def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() - or - def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) - or - exists(EnhancedForStmt for | - for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and - for.getExpr() = n1.asExpr() and - n1.getType() instanceof Array - ) - | - v.getAnUltimateDefinition() = def and - v.getAUse() = n2.asExpr() - ) - or - exists(Callable c | n1.(InstanceParameterNode).getCallable() = c | - exists(InstanceAccess ia | - ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess() + class Content extends TContent { + string toString() { + this = ContentArray() and result = "array" + or + this = ContentArrayArray() and result = "array array" + } + } + + class ContentFilter extends Content { + Content getAMatchingContent() { result = this } + } + + predicate compatibleContents(Content storeContents, Content loadContents) { + storeContents = loadContents + } + + predicate simpleLocalSmallStep(Node n1, Node n2) { + exists(BaseSsaVariable v, BaseSsaVariable def | + def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() + or + def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) + | + v.getAnUltimateDefinition() = def and + v.getAUse() = n2.asExpr() ) or - n2.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getEnclosingCallable() = c - ) - or - n2.(FieldValueNode).getField().getAnAssignedValue() = n1.asExpr() - or - n2.asExpr().(FieldRead).getField() = n1.(FieldValueNode).getField() - or - exists(EnumType enum, Method getValue | - enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and - getValue.getDeclaringType() = enum and - (getValue.hasName("values") or getValue.hasName("valueOf")) and - n2.asExpr().(MethodAccess).getMethod() = getValue - ) - or - n2.asExpr().(CastingExpr).getExpr() = n1.asExpr() - or - n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr() - or - n2.asExpr().(AssignExpr).getSource() = n1.asExpr() - or - n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() - or - n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() - or - n2.asExpr().(ArrayAccess).getArray() = n1.asExpr() - or - exists(Argument arg | - n1.asExpr() = arg and arg.isVararg() and n2.(ImplicitVarargsArray).getCall() = arg.getCall() - ) - or - exists(AssignExpr a, Variable v | - a.getSource() = n1.asExpr() and - a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and - n2.asExpr() = v.getAnAccess().(RValue) - ) - or - exists(Variable v, MethodAccess put, MethodAccess get | - put.getArgument(1) = n1.asExpr() and - put.getMethod().(MapMethod).hasName("put") and - put.getQualifier() = v.getAnAccess() and - get.getQualifier() = v.getAnAccess() and - get.getMethod().(MapMethod).hasName("get") and - n2.asExpr() = get - ) - or - exists(Variable v, MethodAccess add | - add.getAnArgument() = n1.asExpr() and - add.getMethod().(CollectionMethod).hasName("add") and - add.getQualifier() = v.getAnAccess() - | - exists(MethodAccess get | + exists(Callable c | n1.(DataFlow::InstanceParameterNode).getCallable() = c | + exists(InstanceAccess ia | + ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess() + ) + or + n2.(DataFlow::ImplicitInstanceAccess) + .getInstanceAccess() + .(OwnInstanceAccess) + .getEnclosingCallable() = c + ) + or + n2.asExpr().(CastingExpr).getExpr() = n1.asExpr() + or + n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr() + or + n2.asExpr().(AssignExpr).getSource() = n1.asExpr() + or + n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() + } + + predicate levelStepNoCall(Node n1, LocalSourceNode n2) { + exists(EnumType enum, Method getValue | + enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and + getValue.getDeclaringType() = enum and + getValue.hasName("valueOf") and + n2.asExpr().(MethodAccess).getMethod() = getValue + ) + or + exists(Variable v, MethodAccess put, MethodAccess get | + put.getArgument(1) = n1.asExpr() and + put.getMethod().(MapMethod).hasName("put") and + put.getQualifier() = v.getAnAccess() and get.getQualifier() = v.getAnAccess() and - get.getMethod().(CollectionMethod).hasName("get") and + get.getMethod().(MapMethod).hasName("get") and n2.asExpr() = get ) or - exists(EnhancedForStmt for, BaseSsaVariable ssa, BaseSsaVariable def | - for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and - for.getExpr() = v.getAnAccess() and - ssa.getAnUltimateDefinition() = def and - ssa.getAUse() = n2.asExpr() + exists(Variable v, MethodAccess add | + add.getAnArgument() = n1.asExpr() and + add.getMethod().(CollectionMethod).hasName("add") and + add.getQualifier() = v.getAnAccess() + | + exists(MethodAccess get | + get.getQualifier() = v.getAnAccess() and + get.getMethod().(CollectionMethod).hasName("get") and + n2.asExpr() = get + ) + or + exists(EnhancedForStmt for, BaseSsaVariable ssa, BaseSsaVariable def | + for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and + for.getExpr() = v.getAnAccess() and + ssa.getAnUltimateDefinition() = def and + ssa.getAUse() = n2.asExpr() + ) ) - ) + } + + predicate levelStepCall(Node n1, LocalSourceNode n2) { none() } + + predicate storeStep(Node n1, Node n2, Content f) { + exists(EnumType enum, Method getValue | + enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and + getValue.getDeclaringType() = enum and + getValue.hasName("values") and + n2.asExpr().(MethodAccess).getMethod() = getValue and + f = ContentArray() + ) + or + n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() and + f = ContentArray() + or + exists(Argument arg | + n1.asExpr() = arg and + arg.isVararg() and + n2.(DataFlow::ImplicitVarargsArray).getCall() = arg.getCall() and + f = ContentArray() + ) + or + exists(AssignExpr a, Variable v | + a.getSource() = n1.asExpr() and + a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and + n2.asExpr() = v.getAnAccess().(RValue) and + f = ContentArray() + ) + } + + predicate loadStep(Node n1, LocalSourceNode n2, Content f) { + exists(BaseSsaVariable v, BaseSsaVariable def | + exists(EnhancedForStmt for | + for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and + for.getExpr() = n1.asExpr() and + n1.getType() instanceof Array and + f = ContentArray() + ) + | + v.getAnUltimateDefinition() = def and + v.getAUse() = n2.asExpr() + ) + or + n2.asExpr().(ArrayAccess).getArray() = n1.asExpr() + } + + predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content f1, Content f2) { + loadStep(nodeFrom, nodeTo, ContentArray()) and + f1 = ContentArrayArray() and + f2 = ContentArray() + or + storeStep(nodeFrom, nodeTo, ContentArray()) and + f1 = ContentArray() and + f2 = ContentArrayArray() + } + + predicate withContentStep(Node nodeFrom, LocalSourceNode nodeTo, ContentFilter f) { none() } + + predicate withoutContentStep(Node nodeFrom, LocalSourceNode nodeTo, ContentFilter f) { none() } + + predicate jumpStep(Node n1, LocalSourceNode n2) { + n2.(DataFlow::FieldValueNode).getField().getAnAssignedValue() = n1.asExpr() + or + n2.asExpr().(FieldRead).getField() = n1.(DataFlow::FieldValueNode).getField() + } + + predicate hasFeatureBacktrackStoreTarget() { none() } } -/** - * Holds if `n` is forward-reachable from a relevant `ClassInstanceExpr`. - */ -private predicate nodeCandFwd(Node n) { - dispatchOrigin(n.asExpr(), _, _) - or - exists(Node mid | nodeCandFwd(mid) | flowStep(mid, n) or callFlowStepCand(mid, n)) +private predicate lambdaSource(RelevantNode n) { dispatchOrigin(n.asExpr(), _, _) } + +private predicate lambdaSink(RelevantNode n) { + exists(MethodAccess ma | dispatchOrigin(_, ma, _) | n = DataFlow::getInstanceArgument(ma)) } -/** - * Holds if `n` may occur on a dispatch flow path. That is, a path from a - * relevant `ClassInstanceExpr` to a qualifier of a relevant `MethodAccess`. - */ -private predicate nodeCand(Node n) { - exists(MethodAccess ma | - dispatchOrigin(_, ma, _) and - n = getInstanceArgument(ma) and - nodeCandFwd(n) - ) - or - exists(Node mid | nodeCand(mid) | flowStep(n, mid) or callFlowStepCand(n, mid)) and - nodeCandFwd(n) +private signature Method methodDispatchSig(MethodAccess ma); + +private module TrackLambda { + private Callable dispatch(Call c) { + result = dispatchCand(c) or + result = lambdaDispatch0(c) + } + + /** + * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. + * The instance parameter is considered to have index `-1`. + */ + pragma[nomagic] + private predicate paramCand(Call call, int i, DataFlow::ParameterNode p) { + exists(DataFlowPrivate::DataFlowCallable callable | + callable.asCallable() = dispatch(call) and + p.isParameterOf(callable, i) and + p instanceof RelevantNode + ) + } + + /** + * Holds if `arg` is a possible argument to `p` taking virtual dispatch into account. + */ + private predicate argParamCand(DataFlowPrivate::ArgumentNode arg, DataFlow::ParameterNode p) { + exists(int i, DataFlowPrivate::DataFlowCall call | + paramCand(call.asCall(), i, p) and + arg.argumentOf(call, i) + ) + } + + private module TtInput implements TypeTrackingInput { + import TypeTrackingSteps + + predicate callStep(Node n1, LocalSourceNode n2) { argParamCand(n1, n2) } + + predicate returnStep(Node n1, LocalSourceNode n2) { + exists(ReturnStmt ret, Method m | + ret.getEnclosingCallable() = m and + ret.getResult() = n1.asExpr() and + m = dispatch(n2.asExpr()) + ) + } + } + + private import TypeTracking::TypeTrack::Graph + + private predicate edgePlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2) + + private predicate pairCand(PathNode p1, PathNode p2, Method m, MethodAccess ma) { + exists(ClassInstanceExpr cie | + dispatchOrigin(cie, ma, m) and + p1.getNode() = DataFlow::exprNode(cie) and + p2.getNode() = DataFlow::getInstanceArgument(ma) and + p1.isSource() and + p2.isSink() + ) + } + + /** + * Holds if there is flow from a `ClassInstanceExpr` instantiating a type that + * declares or inherits the tracked method `result` to the qualifier of `ma` such + * that `ma` may dispatch to `result`. + */ + Method lambdaDispatch(MethodAccess ma) { + exists(PathNode p1, PathNode p2 | + (p1 = p2 or edgePlus(p1, p2)) and + pairCand(p1, p2, result, ma) + ) + } } -/** - * Holds if `n1 -> n2` is a relevant dispatch flow step. - */ -private predicate step(Node n1, Node n2) { - (flowStep(n1, n2) or callFlowStepCand(n1, n2)) and - nodeCand(n1) and - nodeCand(n2) -} +private Method noDisp(MethodAccess ma) { none() } -private predicate stepPlus(Node n1, Node n2) = fastTC(step/2)(n1, n2) +pragma[nomagic] +private Method d1(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } -/** - * Holds if there is flow from a `ClassInstanceExpr` instantiating a type that - * declares or inherits the tracked method `m` to the qualifier of `ma` such - * that `ma` may dispatch to `m`. - */ -pragma[inline] -private predicate hasDispatchFlow(MethodAccess ma, Method m) { - exists(ClassInstanceExpr cie | - dispatchOrigin(cie, ma, m) and - stepPlus(exprNode(cie), getInstanceArgument(ma)) - ) -} +pragma[nomagic] +private Method d2(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } + +pragma[nomagic] +private Method d3(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } + +pragma[nomagic] +private Method d4(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } + +pragma[nomagic] +private Method d5(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } + +pragma[nomagic] +private Method d6(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } /** * Gets a viable dispatch target for `ma`. This is the output dispatch relation. */ Method viableImpl_out(MethodAccess ma) { result = viableImpl_inp(ma) and - (hasDispatchFlow(ma, result) or not dispatchOrigin(_, ma, result)) + (result = d6(ma) or not dispatchOrigin(_, ma, result)) } diff --git a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll index 56385e89877..eb1878bf7e4 100644 --- a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll @@ -99,10 +99,12 @@ private module Dispatch { private predicate lowConfidenceDispatchType(SrcRefType t) { t instanceof TypeObject or - t instanceof FunctionalInterface + t instanceof Interface and not t.fromSource() or t.hasQualifiedName("java.io", "Serializable") or + t.hasQualifiedName("java.lang", "Iterable") + or t.hasQualifiedName("java.lang", "Cloneable") or t.getPackage().hasName("java.util") and t instanceof Interface diff --git a/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll b/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll index 8328a9dfbcb..64e38a19e9d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/ApacheHttp.qll @@ -4,7 +4,6 @@ import java private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow class ApacheHttpGetParams extends Method { ApacheHttpGetParams() { @@ -42,17 +41,6 @@ class TypeApacheHttpRequestBuilder extends Class { } } -private class ApacheHttpSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http.protocol;HttpRequestHandler;true;handle;(HttpRequest,HttpResponse,HttpContext);;Parameter[0];remote;manual", - "org.apache.hc.core5.http.io;HttpRequestHandler;true;handle;(ClassicHttpRequest,ClassicHttpResponse,HttpContext);;Parameter[0];remote;manual", - "org.apache.hc.core5.http.io;HttpServerRequestHandler;true;handle;(ClassicHttpRequest,ResponseTrigger,HttpContext);;Parameter[0];remote;manual" - ] - } -} - /** * A call that sets a header of an `HttpResponse`. */ @@ -80,191 +68,3 @@ class ApacheHttpSetHeader extends Call { /** Gets the expression used as the value of this header. */ Expr getValue() { result = this.getArgument(1) } } - -private class ApacheHttpXssSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpResponse;true;setEntity;(HttpEntity);;Argument[0];xss;manual", - "org.apache.http.util;EntityUtils;true;updateEntity;(HttpResponse,HttpEntity);;Argument[1];xss;manual", - "org.apache.hc.core5.http;HttpEntityContainer;true;setEntity;(HttpEntity);;Argument[0];xss;manual" - ] - } -} - -private class ApacheHttpOpenUrlSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpRequest;true;setURI;;;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(RequestLine);;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String,ProtocolVersion);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(RequestLine);;Argument[0];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String);;Argument[1];open-url;manual", - "org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String,ProtocolVersion);;Argument[1];open-url;manual", - "org.apache.http.client.methods;HttpGet;false;HttpGet;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpHead;false;HttpHead;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPut;false;HttpPut;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPost;false;HttpPost;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpDelete;false;HttpDelete;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpOptions;false;HttpOptions;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpTrace;false;HttpTrace;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpPatch;false;HttpPatch;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;HttpRequestBase;true;setURI;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;setUri;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;get;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;post;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;put;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;options;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;head;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;delete;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;trace;;;Argument[0];open-url;manual", - "org.apache.http.client.methods;RequestBuilder;false;patch;;;Argument[0];open-url;manual" - ] - } -} - -private class ApacheHttpFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.http;HttpMessage;true;getAllHeaders;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getFirstHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getLastHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getHeaders;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;getParams;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;headerIterator;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpMessage;true;headerIterator;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpRequest;true;getRequestLine;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntityEnclosingRequest;true;getEntity;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;Header;true;getElements;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameter;(int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameterByName;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderElement;true;getParameters;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;NameValuePair;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;NameValuePair;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HeaderIterator;true;nextHeader;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContent;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContentEncoding;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;HttpEntity;true;getContentType;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getParameter;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getDoubleParameter;(String,double);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getIntParameter;(String,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getLongParameter;(String,long);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.params;HttpParams;true;getDoubleParameter;(String,double);;Argument[1];ReturnValue;value;manual", - "org.apache.http.params;HttpParams;true;getIntParameter;(String,int);;Argument[1];ReturnValue;value;manual", - "org.apache.http.params;HttpParams;true;getLongParameter;(String,long);;Argument[1];ReturnValue;value;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getFirstHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getLastHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeader;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeaders;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;getHeaders;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;headerIterator;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;MessageHeaders;true;headerIterator;(String);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getAuthority;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getPath;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpRequest;true;getRequestUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntityContainer;true;getEntity;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;NameValuePair;true;getName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;NameValuePair;true;getValue;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntity;true;getContent;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;HttpEntity;true;getTrailers;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getContentType;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getContentEncoding;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http;EntityDetails;true;getTrailerNames;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;getMethod;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;getUri;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;RequestLine;(HttpRequest);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.message;RequestLine;true;RequestLine;(String,String,ProtocolVersion);;Argument[1];Argument[-1];taint;manual", - "org.apache.hc.core5.function;Supplier;true;get;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.net;URIAuthority;true;getHostName;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.net;URIAuthority;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;toByteArray;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;getContentCharSet;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EntityUtils;true;getContentMimeType;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;toByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;EntityUtils;true;parse;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getAsciiBytes;(String);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getAsciiString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getBytes;(String,String);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;EncodingUtils;true;getString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value;manual", - "org.apache.http.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notEmpty;(Object,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;create;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;createGzipped;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;createUrlEncoded;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;gzip;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntities;true;withTrailers;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;BasicHttpEntity;true;setContent;(InputStream);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.entity;BufferedHttpEntity;true;BufferedHttpEntity;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;ByteArrayEntity;true;ByteArrayEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.http.entity;HttpEntityWrapper;true;HttpEntityWrapper;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;InputStreamEntity;true;InputStreamEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.http.entity;StringEntity;true;StringEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.io.entity;BasicHttpEntity;true;BasicHttpEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;BufferedHttpEntity;true;BufferedHttpEntity;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;ByteArrayEntity;true;ByteArrayEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.http.io.entity;HttpEntityWrapper;true;HttpEntityWrapper;(HttpEntity);;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;InputStreamEntity;true;InputStreamEntity;;;Argument[0];ReturnValue;taint;manual", - "org.apache.hc.core5.http.io.entity;StringEntity;true;StringEntity;;;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;buffer;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;ByteArrayBuffer;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(ByteArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(CharArrayBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;append;(Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.http.util;CharArrayBuffer;true;buffer;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;toCharArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;array;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;ByteArrayBuffer;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(CharArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(ByteArrayBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(CharArrayBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;append;(Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;array;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;toCharArray;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint;manual", - "org.apache.http.message;BasicRequestLine;false;BasicRequestLine;;;Argument[1];Argument[-1];taint;manual", - "org.apache.http;RequestLine;true;getUri;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.http;RequestLine;true;toString;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll b/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll index 615d928a709..55a8e262438 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Flexjson.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The class `flexjson.JSONDeserializer`. */ class FlexjsonDeserializer extends RefType { @@ -33,9 +32,3 @@ class FlexjsonDeserializerUseMethod extends Method { this.hasName("use") } } - -private class FluentUseMethodModel extends SummaryModelCsv { - override predicate row(string r) { - r = "flexjson;JSONDeserializer;true;use;;;Argument[-1];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll b/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll deleted file mode 100644 index c12c6c3be16..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/GeneratedNegative.qll +++ /dev/null @@ -1,8 +0,0 @@ -/** Provides a module for importing negative models. */ - -/** - * A module importing all generated negative Models as Data models. - */ -private module GeneratedFrameworks { - private import apache.NegativeIOGenerated -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll b/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll index 4832576b7b9..28b28101454 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Hibernate.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The interface `org.hibernate.query.QueryProducer`. */ class HibernateQueryProducer extends RefType { @@ -21,19 +20,3 @@ class HibernateSharedSessionContract extends RefType { class HibernateSession extends RefType { HibernateSession() { this.hasQualifiedName("org.hibernate", "Session") } } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.hibernate;QueryProducer;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;QueryProducer;true;createNativeQuery;;;Argument[0];sql;manual", - "org.hibernate;QueryProducer;true;createSQLQuery;;;Argument[0];sql;manual", - "org.hibernate;SharedSessionContract;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;SharedSessionContract;true;createSQLQuery;;;Argument[0];sql;manual", - "org.hibernate;Session;true;createQuery;;;Argument[0];sql;manual", - "org.hibernate;Session;true;createSQLQuery;;;Argument[0];sql;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll b/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll deleted file mode 100644 index 05f764b357b..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/HikariCP.qll +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Definitions of sinks in the Hikari Connection Pool library. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "com.zaxxer.hikari;HikariConfig;false;HikariConfig;(Properties);;Argument[0];jdbc-url;manual", - "com.zaxxer.hikari;HikariConfig;false;setJdbcUrl;(String);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JMS.qll b/java/ql/lib/semmle/code/java/frameworks/JMS.qll deleted file mode 100644 index f1eb0ace982..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JMS.qll +++ /dev/null @@ -1,112 +0,0 @@ -/** - * This model covers JMS API versions 1 and 2. - * - * https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html - * https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** Defines sources of tainted data in JMS 1. */ -private class Jms1Source extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // incoming messages are considered tainted - "javax.jms;MessageListener;true;onMessage;(Message);;Parameter[0];remote;manual", - "javax.jms;MessageConsumer;true;receive;;;ReturnValue;remote;manual", - "javax.jms;MessageConsumer;true;receiveNoWait;();;ReturnValue;remote;manual", - "javax.jms;QueueRequestor;true;request;(Message);;ReturnValue;remote;manual", - "javax.jms;TopicRequestor;true;request;(Message);;ReturnValue;remote;manual", - ] - } -} - -/** Defines taint propagation steps in JMS 1. */ -private class Jms1FlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // if a message is tainted, then it returns tainted data - "javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSCorrelationIDAsBytes;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSCorrelationID;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSReplyTo;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSDestination;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getJMSType;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getBooleanProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getByteProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getShortProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getIntProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getLongProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getFloatProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getDoubleProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getStringProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getObjectProperty;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Message;true;getPropertyNames;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUnsignedByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUnsignedShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readChar;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readInt;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readLong;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readFloat;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readDouble;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readUTF;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;BytesMessage;true;readBytes;;;Argument[-1];Argument[0];taint;manual", - "javax.jms;MapMessage;true;getBoolean;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getByte;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getShort;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getChar;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getInt;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getLong;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getFloat;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getDouble;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getString;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getBytes;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getObject;(String);;Argument[-1];ReturnValue;taint;manual", - "javax.jms;MapMessage;true;getMapNames;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;ObjectMessage;true;getObject;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readByte;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readShort;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readChar;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readInt;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readLong;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readFloat;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readDouble;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readString;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;StreamMessage;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual", - "javax.jms;StreamMessage;true;readObject;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;TextMessage;true;getText;();;Argument[-1];ReturnValue;taint;manual", - // if a destination is tainted, then it returns tainted data - "javax.jms;Queue;true;getQueueName;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Queue;true;toString;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Topic;true;getTopicName;();;Argument[-1];ReturnValue;taint;manual", - "javax.jms;Topic;true;toString;();;Argument[-1];ReturnValue;taint;manual", - ] - } -} - -/** Defines additional sources of tainted data in JMS 2. */ -private class Jms2Source extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "javax.jms;JMSConsumer;true;receive;;;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveBody;;;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveNoWait;();;ReturnValue;remote;manual", - "javax.jms;JMSConsumer;true;receiveBodyNoWait;();;ReturnValue;remote;manual", - ] - } -} - -/** Defines additional taint propagation steps in JMS 2. */ -private class Jms2FlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = "javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll b/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll deleted file mode 100644 index 8748c2a0cb1..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JavaIo.qll +++ /dev/null @@ -1,24 +0,0 @@ -/** Definitions of taint steps in Objects class of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class JavaIoSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.lang;Appendable;true;append;;;Argument[0];Argument[-1];taint;manual", - "java.lang;Appendable;true;append;;;Argument[-1];ReturnValue;value;manual", - "java.io;Writer;true;write;;;Argument[0];Argument[-1];taint;manual", - "java.io;Writer;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;CharArrayWriter;true;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "java.io;ObjectInput;true;read;;;Argument[-1];Argument[0];taint;manual", - "java.io;DataInput;true;readFully;;;Argument[-1];Argument[0];taint;manual", - "java.io;DataInput;true;readLine;();;Argument[-1];ReturnValue;taint;manual", - "java.io;DataInput;true;readUTF;();;Argument[-1];ReturnValue;taint;manual", - "java.nio.channels;ReadableByteChannel;true;read;(ByteBuffer);;Argument[-1];Argument[0];taint;manual", - "java.nio.channels;Channels;false;newChannel;(InputStream);;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll b/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll deleted file mode 100644 index 0a2db0d06fc..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JavaxJson.qll +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Provides models for the `javax.json` and `jakarta.json` packages. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + - [ - ".json;Json;false;createArrayBuilder;(JsonArray);;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createArrayBuilder;(Collection);;Argument[0].Element;ReturnValue;taint;manual", - ".json;Json;false;createDiff;;;Argument[0..1];ReturnValue;taint;manual", - ".json;Json;false;createMergeDiff;;;Argument[0..1];ReturnValue;taint;manual", - ".json;Json;false;createMergePatch;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(JsonObject);;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(Map);;Argument[0].MapKey;ReturnValue;taint;manual", - ".json;Json;false;createObjectBuilder;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - ".json;Json;false;createPatch;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createPatchBuilder;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createPointer;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createReader;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createValue;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;createWriter;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;decodePointer;;;Argument[0];ReturnValue;taint;manual", - ".json;Json;false;encodePointer;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonArray;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getBoolean;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getInt;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonNumber;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getJsonString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArray;false;getString;;;Argument[1];ReturnValue;value;manual", - ".json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArrayBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;add;(boolean);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(double);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(long);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonArrayBuilder);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonObjectBuilder);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(JsonValue);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(String);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(BigDecimal);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(BigInteger);;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,boolean);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,double);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,int);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,long);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonArrayBuilder);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonObjectBuilder);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,JsonValue);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,String);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,BigDecimal);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;add;(int,BigInteger);;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;addAll;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;addAll;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;addNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonArrayBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;set;;;Argument[1];Argument[-1];taint;manual", - ".json;JsonArrayBuilder;false;set;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonArrayBuilder;false;setNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonMergePatch;false;apply;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonMergePatch;false;apply;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonMergePatch;false;toJsonValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigDecimalValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigIntegerValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;bigIntegerValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;doubleValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;intValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;intValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;longValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;longValueExact;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonNumber;false;numberValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getBoolean;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObject;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getInt;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObject;false;getJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonNumber;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getJsonString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObject;false;getString;;;Argument[1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;add;;;Argument[1];Argument[-1];taint;manual", - ".json;JsonObjectBuilder;false;addAll;;;Argument[0];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;addAll;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;addNull;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonObjectBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonObjectBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatch;false;apply;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatch;false;apply;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPatch;false;toJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;add;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;add;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;copy;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;copy;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;move;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;move;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;remove;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;remove;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;replace;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPatchBuilder;false;test;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPatchBuilder;false;test;;;Argument[-1];ReturnValue;value;manual", - ".json;JsonPointer;false;add;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonPointer;false;add;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPointer;false;getValue;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPointer;false;remove;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonPointer;false;replace;;;Argument[0..1];ReturnValue;taint;manual", - ".json;JsonPointer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;read;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReader;false;readValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint;manual", - ".json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonStructure;true;getValue;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;asJsonArray;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;asJsonObject;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonValue;true;toString;;;Argument[-1];ReturnValue;taint;manual", - ".json;JsonWriter;false;write;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriter;false;writeArray;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriter;false;writeObject;;;Argument[0];Argument[-1];taint;manual", - ".json;JsonWriterFactory;false;createWriter;;;Argument[-1];Argument[0];taint;manual", - ".json.stream;JsonParserFactory;false;createParser;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll index c60c3ff0369..54b41f28a08 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll @@ -4,7 +4,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.security.XSS /** @@ -321,323 +320,6 @@ private class JaxRSXssSink extends XssSink { } } -/** A URL redirection sink from JAX-RS */ -private class JaxRsUrlRedirectSink extends SinkModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response;true;" + ["seeOther", "temporaryRedirect"] + - ";;;Argument[0];url-redirect;manual" - } -} - -/** - * Model Response: - * - * - the returned ResponseBuilder gains taint from a tainted entity or existing Response - */ -private class ResponseModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response;false;" + ["accepted", "fromResponse", "ok"] + - ";;;Argument[0];ReturnValue;taint;manual" - } -} - -/** - * Model ResponseBuilder: - * - * - becomes tainted by a tainted entity, but not by metadata, headers etc - * - build() method returns taint - * - almost all methods are fluent, and so preserve value - */ -private class ResponseBuilderModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Response$ResponseBuilder;true;" + - [ - "allow", "cacheControl", "contentLocation", "cookie", "encoding", "entity", "expires", - "header", "language", "lastModified", "link", "links", "location", "replaceAll", "status", - "tag", "type", "variant", "variants" - ] + ";;;Argument[-1];ReturnValue;value;manual" - or - row = - ["javax", "jakarta"] + ".ws.rs.core;Response$ResponseBuilder;true;" + - [ - "build;;;Argument[-1];ReturnValue;taint;manual", - "entity;;;Argument[0];Argument[-1];taint;manual", - "clone;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model HttpHeaders: methods that Date have to be syntax-checked, but those returning MediaType - * or Locale are assumed potentially dangerous, as these types do not generally check that the - * input data is recognised, only that it conforms to the expected syntax. - */ -private class HttpHeadersModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;HttpHeaders;true;" + - [ - "getAcceptableLanguages", "getAcceptableMediaTypes", "getCookies", "getHeaderString", - "getLanguage", "getMediaType", "getRequestHeader", "getRequestHeaders" - ] + ";;;Argument[-1];ReturnValue;taint;manual" - } -} - -/** - * Model MultivaluedMap, which extends `Map>` and provides a few extra helper methods. - */ -private class MultivaluedMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MultivaluedMap;true;" + - [ - "add;;;Argument[0];Argument[-1].MapKey;value;manual", - "add;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "addAll;;;Argument[0];Argument[-1].MapKey;value;manual", - "addAll;(Object,List);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - "addAll;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].MapValue.Element;value;manual", - "addFirst;;;Argument[0];Argument[-1].MapKey;value;manual", - "addFirst;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "getFirst;;;Argument[-1].MapValue.Element;ReturnValue;value;manual", - "putSingle;;;Argument[0];Argument[-1].MapKey;value;manual", - "putSingle;;;Argument[1];Argument[-1].MapValue.Element;value;manual" - ] - } -} - -/** - * Model AbstractMultivaluedMap, which implements MultivaluedMap. - */ -private class AbstractMultivaluedMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;" + - [ - "Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Model MultivaluedHashMap, which extends AbstractMultivaluedMap. - */ -private class MultivaluedHashMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;" + - [ - "(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - "(MultivaluedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "(MultivaluedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Model PathSegment, which wraps a path and its associated matrix parameters. - */ -private class PathSegmentModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;PathSegment;true;" + ["getMatrixParameters", "getPath"] + - ";;;Argument[-1];ReturnValue;taint;manual" - } -} - -/** - * Model UriInfo, which provides URI element accessors. - */ -private class UriInfoModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;UriInfo;true;" + - [ - "getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "getAbsolutePathBuilder;;;Argument[-1];ReturnValue;taint;manual", - "getPath;;;Argument[-1];ReturnValue;taint;manual", - "getPathParameters;;;Argument[-1];ReturnValue;taint;manual", - "getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "getQueryParameters;;;Argument[-1];ReturnValue;taint;manual", - "getRequestUri;;;Argument[-1];ReturnValue;taint;manual", - "getRequestUriBuilder;;;Argument[-1];ReturnValue;taint;manual", - "relativize;;;Argument[0];ReturnValue;taint;manual", - "resolve;;;Argument[-1];ReturnValue;taint;manual", - "resolve;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model Cookie, a simple tuple type. - */ -private class CookieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Cookie;" + - [ - "true;getDomain;;;Argument[-1];ReturnValue;taint;manual", - "true;getName;;;Argument[-1];ReturnValue;taint;manual", - "true;getPath;;;Argument[-1];ReturnValue;taint;manual", - "true;getValue;;;Argument[-1];ReturnValue;taint;manual", - "true;getVersion;;;Argument[-1];ReturnValue;taint;manual", - "true;toString;;;Argument[-1];ReturnValue;taint;manual", - "false;Cookie;;;Argument[0..4];Argument[-1];taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model NewCookie, a simple tuple type. - */ -private class NewCookieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;NewCookie;" + - [ - "true;getComment;;;Argument[-1];ReturnValue;taint;manual", - "true;getExpiry;;;Argument[-1];ReturnValue;taint;manual", - "true;getMaxAge;;;Argument[-1];ReturnValue;taint;manual", - "true;toCookie;;;Argument[-1];ReturnValue;taint;manual", - "false;NewCookie;;;Argument[0..9];Argument[-1];taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Model Form, a simple container type. - */ -private class FormModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;Form;" + - [ - "false;Form;;;Argument[0].MapKey;Argument[-1];taint;manual", - "false;Form;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "false;Form;;;Argument[0..1];Argument[-1];taint;manual", - "true;asMap;;;Argument[-1];ReturnValue;taint;manual", - "true;param;;;Argument[0..1];Argument[-1];taint;manual", - "true;param;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -/** - * Model GenericEntity, a wrapper for HTTP entities (e.g., documents). - */ -private class GenericEntityModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;GenericEntity;" + - [ - "false;GenericEntity;;;Argument[0];Argument[-1];taint;manual", - "true;getEntity;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model MediaType, which provides accessors for elements of Content-Type and similar - * media type specifications. - */ -private class MediaTypeModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;MediaType;" + - [ - "false;MediaType;;;Argument[0..2];Argument[-1];taint;manual", - "true;getParameters;;;Argument[-1];ReturnValue;taint;manual", - "true;getSubtype;;;Argument[-1];ReturnValue;taint;manual", - "true;getType;;;Argument[-1];ReturnValue;taint;manual", - "false;valueOf;;;Argument[0];ReturnValue;taint;manual", - "true;withCharset;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** - * Model UriBuilder, which provides a fluent interface to build a URI from components. - */ -private class UriBuilderModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["javax", "jakarta"] + ".ws.rs.core;UriBuilder;" + - [ - "true;build;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;build;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromEncoded;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;buildFromEncoded;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;buildFromEncodedMap;;;Argument[-1];ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;buildFromMap;;;Argument[-1];ReturnValue;taint;manual", - "true;clone;;;Argument[-1];ReturnValue;taint;manual", - "true;fragment;;;Argument[0];ReturnValue;taint;manual", - "true;fragment;;;Argument[-1];ReturnValue;value;manual", - "false;fromLink;;;Argument[0];ReturnValue;taint;manual", - "false;fromPath;;;Argument[0];ReturnValue;taint;manual", - "false;fromUri;;;Argument[0];ReturnValue;taint;manual", - "true;host;;;Argument[0];ReturnValue;taint;manual", - "true;host;;;Argument[-1];ReturnValue;value;manual", - "true;matrixParam;;;Argument[0];ReturnValue;taint;manual", - "true;matrixParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;matrixParam;;;Argument[-1];ReturnValue;value;manual", - "true;path;;;Argument[0..1];ReturnValue;taint;manual", - "true;path;;;Argument[-1];ReturnValue;value;manual", - "true;queryParam;;;Argument[0];ReturnValue;taint;manual", - "true;queryParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;queryParam;;;Argument[-1];ReturnValue;value;manual", - "true;replaceMatrix;;;Argument[0];ReturnValue;taint;manual", - "true;replaceMatrix;;;Argument[-1];ReturnValue;value;manual", - "true;replaceMatrixParam;;;Argument[0];ReturnValue;taint;manual", - "true;replaceMatrixParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;replaceMatrixParam;;;Argument[-1];ReturnValue;value;manual", - "true;replacePath;;;Argument[0];ReturnValue;taint;manual", - "true;replacePath;;;Argument[-1];ReturnValue;value;manual", - "true;replaceQuery;;;Argument[0];ReturnValue;taint;manual", - "true;replaceQuery;;;Argument[-1];ReturnValue;value;manual", - "true;replaceQueryParam;;;Argument[0];ReturnValue;taint;manual", - "true;replaceQueryParam;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "true;replaceQueryParam;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplate;;;Argument[0..2];ReturnValue;taint;manual", - "true;resolveTemplate;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplateFromEncoded;;;Argument[0..1];ReturnValue;taint;manual", - "true;resolveTemplateFromEncoded;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplates;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;resolveTemplates;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;resolveTemplates;;;Argument[-1];ReturnValue;value;manual", - "true;resolveTemplatesFromEncoded;;;Argument[0].MapKey;ReturnValue;taint;manual", - "true;resolveTemplatesFromEncoded;;;Argument[0].MapValue;ReturnValue;taint;manual", - "true;resolveTemplatesFromEncoded;;;Argument[-1];ReturnValue;value;manual", - "true;scheme;;;Argument[0];ReturnValue;taint;manual", - "true;scheme;;;Argument[-1];ReturnValue;value;manual", - "true;schemeSpecificPart;;;Argument[0];ReturnValue;taint;manual", - "true;schemeSpecificPart;;;Argument[-1];ReturnValue;value;manual", - "true;segment;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "true;segment;;;Argument[-1];ReturnValue;value;manual", - "true;toTemplate;;;Argument[-1];ReturnValue;taint;manual", - "true;uri;;;Argument[0];ReturnValue;taint;manual", - "true;uri;;;Argument[-1];ReturnValue;value;manual", - "true;userInfo;;;Argument[0];ReturnValue;taint;manual", - "true;userInfo;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class JaxRsUrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = ["javax", "jakarta"] + ".ws.rs.client;Client;true;target;;;Argument[0];open-url;manual" - } -} - private predicate isXssVulnerableContentTypeExpr(Expr e) { isXssVulnerableContentType(getContentTypeString(e)) } @@ -784,17 +466,3 @@ private class VulnerableEntity extends XssSinkBarrier { ).getArgument(0) } } - -/** - * Model sources stemming from `ContainerRequestContext`. - */ -private class ContainerRequestContextModel extends SourceModelCsv { - override predicate row(string s) { - s = - ["javax", "jakarta"] + ".ws.rs.container;ContainerRequestContext;true;" + - [ - "getAcceptableLanguages", "getAcceptableMediaTypes", "getCookies", "getEntityStream", - "getHeaders", "getHeaderString", "getLanguage", "getMediaType", "getUriInfo" - ] + ";;;ReturnValue;remote;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll index ba9dd8d445c..6807a976e77 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Jdbc.qll @@ -2,7 +2,7 @@ * Provides classes and predicates for working with the Java JDBC API. */ -private import semmle.code.java.dataflow.ExternalFlow +import java /*--- Types ---*/ /** The interface `java.sql.Connection`. */ @@ -34,33 +34,3 @@ class ResultSetGetStringMethod extends Method { getReturnType() instanceof TypeString } } - -/*--- Other definitions ---*/ -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "java.sql;Connection;true;prepareStatement;;;Argument[0];sql;manual", - "java.sql;Connection;true;prepareCall;;;Argument[0];sql;manual", - "java.sql;Statement;true;execute;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeQuery;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeUpdate;;;Argument[0];sql;manual", - "java.sql;Statement;true;executeLargeUpdate;;;Argument[0];sql;manual", - "java.sql;Statement;true;addBatch;;;Argument[0];sql;manual" - ] - } -} - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "java.sql;DriverManager;false;getConnection;(String);;Argument[0];jdbc-url;manual", - "java.sql;DriverManager;false;getConnection;(String,Properties);;Argument[0];jdbc-url;manual", - "java.sql;DriverManager;false;getConnection;(String,String,String);;Argument[0];jdbc-url;manual", - "java.sql;Driver;false;connect;(String,Properties);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll b/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll deleted file mode 100644 index 698d27d07ed..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Jdbi.qll +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Definitions of sinks in the JDBI library. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.jdbi.v3.core;Jdbi;false;create;(String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;create;(String,Properties);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;create;(String,String,String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String,Properties);;Argument[0];jdbc-url;manual", - "org.jdbi.v3.core;Jdbi;false;open;(String,String,String);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll b/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll index 9ed563091d7..d92b80ca32b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JoddJson.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The class `jodd.json.Parser`. */ class JoddJsonParser extends RefType { @@ -41,28 +40,3 @@ class AllowClassMethod extends Method { this.hasName("allowClass") } } - -/** - * A partial model of jodd.json.JsonParser noting fluent methods. - * - * This means that DataFlow::localFlow and similar methods are aware - * that the result of (e.g.) JsonParser.allowClass is an alias of the - * qualifier. - */ -private class JsonParserFluentMethods extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "jodd.json;JsonParser;false;allowAllClasses;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;allowClass;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;lazy;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;looseMode;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;map;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;setClassMetadataName;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;strictTypes;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;useAltPaths;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;withClassMetadata;;;Argument[-1];ReturnValue;value;manual", - "jodd.json;JsonParser;false;withValueConverter;;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll b/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll deleted file mode 100644 index b8c79a010c0..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/JsonJava.qll +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Provides models for working with the JSON-java library (package `org.json`). - */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.json;JSONString;true;toJSONString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLXsiTypeConverter;true;convert;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;rowToJSONArray;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;rowToJSONObject;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;CDL;false;rowToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;CDL;false;toJSONArray;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;CDL;false;toString;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;Cookie;false;escape;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;Cookie;false;unescape;;;Argument[0];ReturnValue;taint;manual", - "org.json;CookieList;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;CookieList;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTP;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTP;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;HTTPTokener;false;HTTPTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;HTTPTokener;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;JSONArray;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(JSONArray);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(JSONTokener);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(Object);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONArray;false;JSONArray;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;get;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;getString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;iterator;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONArray;false;join;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;join;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;opt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;optString;;;Argument[-1];ReturnValue;taint;manual", - // Default values that may be returned by the `opt*` methods above: - "org.json;JSONArray;false;optBigDecimal;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optBigInteger;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optBoolean;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optDouble;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optEnum;;;Argument[2];ReturnValue;value;manual", - "org.json;JSONArray;false;optFloat;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optInt;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optLong;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optNumber;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;optString;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONArray;false;put;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONArray;false;put;(boolean);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(double);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(float);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(long);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,boolean);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,double);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,float);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,int);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,long);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Map);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Map);;Argument[1].MapValue;Argument[-1];taint;manual", - "org.json;JSONArray;false;put;(int,Object);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONArray;false;putAll;(Collection);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(JSONArray);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;putAll;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONArray;false;query;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;remove;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;toJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONArray;false;toList;;;Argument[0];ReturnValue.Element;taint;manual", - "org.json;JSONArray;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONArray;false;write;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONArray;false;write;;;Argument[0];ReturnValue;value;manual", - "org.json;JSONML;false;toJSONArray;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONML;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONML;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONObject,String[]);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONObject,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(JSONTokener);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object,String[]);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(Object,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;JSONObject;(String,Locale);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;accumulate;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;accumulate;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;append;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;doubleToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;true;entrySet;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;get;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getNames;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.json;JSONObject;false;getNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;getString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;increment;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;increment;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;keys;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;keySet;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.json;JSONObject;false;names;;;Argument[-1];ReturnValue;taint;manual", // Returns a JSONArray, hence this has no Element qualifier or similar - "org.json;JSONObject;false;numberToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;opt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBigDecimal;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBigInteger;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optBoolean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optDouble;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optEnum;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optFloat;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optInt;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optJSONObject;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optLong;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optNumber;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;optString;;;Argument[-1];ReturnValue;taint;manual", - // Default values that may be returned by the `opt*` methods above: - "org.json;JSONObject;false;optBigDecimal;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optBigInteger;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optBoolean;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optDouble;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optEnum;;;Argument[2];ReturnValue;value;manual", - "org.json;JSONObject;false;optFloat;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optInt;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optLong;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optNumber;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;optString;;;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;put;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;put;(String,boolean);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Collection);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,double);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,float);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,int);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,long);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Object);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,boolean);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,double);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,float);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,int);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,long);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Map);;Argument[1].MapValue;Argument[-1];taint;manual", - "org.json;JSONObject;false;put;(String,Object);;Argument[1];Argument[-1];taint;manual", - "org.json;JSONObject;false;putOnce;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;putOnce;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;putOpt;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONObject;false;putOpt;;;Argument[0..1];Argument[-1];taint;manual", - "org.json;JSONObject;false;query;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;quote;(String);;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;quote;(String,Writer);;Argument[0];Argument[1];taint;manual", - "org.json;JSONObject;false;quote;(String,Writer);;Argument[1];ReturnValue;value;manual", - "org.json;JSONObject;false;remove;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;stringToValue;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;toJSONArray;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;toMap;;;Argument[-1];ReturnValue.MapKey;taint;manual", - "org.json;JSONObject;false;toMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.json;JSONObject;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONObject;false;valueToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONObject;false;write;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONObject;false;write;;;Argument[0];ReturnValue;value;manual", - "org.json;JSONPointer;false;JSONPointer;(List);;Argument[0].Element;Argument[-1];taint;manual", - "org.json;JSONPointer;false;JSONPointer;(String);;Argument[0];Argument[-1];taint;manual", - "org.json;JSONPointer;false;queryFrom;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONPointer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONPointer;false;toURIFragment;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONPointer$Builder;false;append;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONPointer$Builder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONPointer$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONStringer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;JSONTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONTokener;true;next;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextClean;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextString;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextTo;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;nextValue;;;Argument[-1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;syntaxError;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;JSONTokener;true;toString;;;Argument[-1];ReturnValue;taint;manual", - // The following model doesn't work yet due to lack of support for reverse taint flow: - "org.json;JSONWriter;true;JSONWriter;;;Argument[-1];Argument[0];taint;manual", - "org.json;JSONWriter;true;key;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONWriter;true;value;;;Argument[0];Argument[-1];taint;manual", - "org.json;JSONWriter;true;valueToString;;;Argument[0];ReturnValue;taint;manual", - "org.json;JSONWriter;true;array;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;endArray;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;endObject;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;key;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;object;;;Argument[-1];ReturnValue;value;manual", - "org.json;JSONWriter;true;value;;;Argument[-1];ReturnValue;value;manual", - "org.json;Property;false;toJSONObject;;;Argument[0].MapKey;ReturnValue;taint;manual", - "org.json;Property;false;toJSONObject;;;Argument[0].MapValue;ReturnValue;taint;manual", - "org.json;Property;false;toProperties;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.json;Property;false;toProperties;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.json;XML;false;escape;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;stringToValue;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;toJSONObject;;;Argument[0];ReturnValue;taint;manual", - "org.json;XML;false;toString;;;Argument[0..1];ReturnValue;taint;manual", - "org.json;XML;false;unescape;;;Argument[0];ReturnValue;taint;manual", - "org.json;XMLTokener;false;XMLTokener;;;Argument[0];Argument[-1];taint;manual", - "org.json;XMLTokener;false;nextCDATA;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextContent;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextEntity;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextMeta;;;Argument[-1];ReturnValue;taint;manual", - "org.json;XMLTokener;false;nextToken;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Logging.qll b/java/ql/lib/semmle/code/java/frameworks/Logging.qll deleted file mode 100644 index 4c00873781c..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Logging.qll +++ /dev/null @@ -1,340 +0,0 @@ -/** Provides classes and predicates to reason about logging. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class LoggingSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[1];Argument[-1];taint;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[-1];taint;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;addMarker;;;Argument[-1];ReturnValue;value;manual", - "org.slf4j.spi;LoggingEventBuilder;true;setCause;;;Argument[-1];ReturnValue;value;manual", - "java.util.logging;LogRecord;false;LogRecord;;;Argument[1];Argument[-1];taint;manual" - ] - } -} - -private string jBossLogger() { result = "org.jboss.logging;" + ["BasicLogger", "Logger"] } - -private class LoggingSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // org.apache.log4j.Category - "org.apache.log4j;Category;true;assertLog;;;Argument[1];logging;manual", - "org.apache.log4j;Category;true;debug;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;error;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;fatal;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;forcedLog;;;Argument[2];logging;manual", - "org.apache.log4j;Category;true;info;;;Argument[0];logging;manual", - "org.apache.log4j;Category;true;l7dlog;(Priority,String,Object[],Throwable);;Argument[2];logging;manual", - "org.apache.log4j;Category;true;log;(Priority,Object);;Argument[1];logging;manual", - "org.apache.log4j;Category;true;log;(Priority,Object,Throwable);;Argument[1];logging;manual", - "org.apache.log4j;Category;true;log;(String,Priority,Object,Throwable);;Argument[2];logging;manual", - "org.apache.log4j;Category;true;warn;;;Argument[0];logging;manual", - // org.apache.logging.log4j.Logger - "org.apache.logging.log4j;Logger;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(CharSequence);;Argument[0];logging;manual", - ";(CharSequence,Throwable);;Argument[0];logging;manual", - ";(Marker,CharSequence);;Argument[1];logging;manual", - ";(Marker,CharSequence,Throwable);;Argument[1];logging;manual", - ";(Marker,Message);;Argument[1];logging;manual", - ";(Marker,MessageSupplier);;Argument[1];logging;manual", - ";(Marker,MessageSupplier);;Argument[1];logging;manual", - ";(Marker,MessageSupplier,Throwable);;Argument[1];logging;manual", - ";(Marker,Object);;Argument[1];logging;manual", - ";(Marker,Object,Throwable);;Argument[1];logging;manual", - ";(Marker,String);;Argument[1];logging;manual", - ";(Marker,String,Object[]);;Argument[1..2];logging;manual", - ";(Marker,String,Object);;Argument[1..2];logging;manual", - ";(Marker,String,Object,Object);;Argument[1..3];logging;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Marker,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];logging;manual", - ";(Marker,String,Supplier);;Argument[1..2];logging;manual", - ";(Marker,String,Throwable);;Argument[1];logging;manual", - ";(Marker,Supplier);;Argument[1];logging;manual", - ";(Marker,Supplier,Throwable);;Argument[1];logging;manual", - ";(MessageSupplier);;Argument[0];logging;manual", - ";(MessageSupplier,Throwable);;Argument[0];logging;manual", - ";(Message);;Argument[0];logging;manual", - ";(Message,Throwable);;Argument[0];logging;manual", - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual", - ";(String);;Argument[0];logging;manual", - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Object,Object,Object);;Argument[0..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[0..5];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging;manual", - ";(String,Supplier);;Argument[0..1];logging;manual", - ";(String,Throwable);;Argument[0];logging;manual", - ";(Supplier);;Argument[0];logging;manual", - ";(Supplier,Throwable);;Argument[0];logging;manual" - ], - "org.apache.logging.log4j;Logger;true;log" + - [ - ";(Level,CharSequence);;Argument[1];logging;manual", - ";(Level,CharSequence,Throwable);;Argument[1];logging;manual", - ";(Level,Marker,CharSequence);;Argument[2];logging;manual", - ";(Level,Marker,CharSequence,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Message);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];logging;manual", - ";(Level,Marker,MessageSupplier,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Object);;Argument[2];logging;manual", - ";(Level,Marker,Object,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,String);;Argument[2];logging;manual", - ";(Level,Marker,String,Object[]);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Object);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Object,Object);;Argument[2..4];logging;manual", - ";(Level,Marker,String,Object,Object,Object);;Argument[2..5];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object);;Argument[2..6];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object);;Argument[2..7];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object);;Argument[2..8];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[2..9];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..10];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..11];logging;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..12];logging;manual", - ";(Level,Marker,String,Supplier);;Argument[2..3];logging;manual", - ";(Level,Marker,String,Throwable);;Argument[2];logging;manual", - ";(Level,Marker,Supplier);;Argument[2];logging;manual", - ";(Level,Marker,Supplier,Throwable);;Argument[2];logging;manual", - ";(Level,Message);;Argument[1];logging;manual", - ";(Level,MessageSupplier);;Argument[1];logging;manual", - ";(Level,MessageSupplier,Throwable);;Argument[1];logging;manual", - ";(Level,Message);;Argument[1];logging;manual", - ";(Level,Message,Throwable);;Argument[1];logging;manual", - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,String);;Argument[1];logging;manual", - ";(Level,Object,Throwable);;Argument[1];logging;manual", - ";(Level,String);;Argument[1];logging;manual", - ";(Level,String,Object[]);;Argument[1..2];logging;manual", - ";(Level,String,Object);;Argument[1..2];logging;manual", - ";(Level,String,Object,Object);;Argument[1..3];logging;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];logging;manual", - ";(Level,String,Supplier);;Argument[1..2];logging;manual", - ";(Level,String,Throwable);;Argument[1];logging;manual", - ";(Level,Supplier);;Argument[1];logging;manual", - ";(Level,Supplier,Throwable);;Argument[1];logging;manual" - ], "org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;logMessage;(Level,Marker,String,StackTraceElement,Message,Throwable);;Argument[4];logging;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,Marker,String,Object[]);;Argument[2..3];logging;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,String,Object[]);;Argument[1..2];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];logging;manual", - "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[0..1];logging;manual", - // org.apache.logging.log4j.LogBuilder - "org.apache.logging.log4j;LogBuilder;true;log;(CharSequence);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Message);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Object);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String);;Argument[0];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object[]);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object);;Argument[0..2];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object);;Argument[0..3];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object);;Argument[0..5];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Supplier);;Argument[0..1];logging;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Supplier);;Argument[0];logging;manual", - // org.apache.commons.logging.Log - "org.apache.commons.logging;Log;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + ";;;Argument[0];logging;manual", - // org.jboss.logging.BasicLogger and org.jboss.logging.Logger - // (org.jboss.logging.Logger does not implement BasicLogger in some implementations like JBoss Application Server 4.0.4) - jBossLogger() + ";true;" + ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual", - ";(Object,Object[]);;Argument[0..1];logging;manual", - ";(Object,Object[],Throwable);;Argument[0..1];logging;manual", - ";(String,Object,Object[],Throwable);;Argument[1..2];logging;manual", - ";(String,Object,Throwable);;Argument[1];logging;manual" - ], - jBossLogger() + ";true;log" + - [ - ";(Level,Object);;Argument[1];logging;manual", - ";(Level,Object,Object[]);;Argument[1..2];logging;manual", - ";(Level,Object,Object[],Throwable);;Argument[1..2];logging;manual", - ";(Level,Object,Throwable);;Argument[1];logging;manual", - ";(Level,String,Object,Throwable);;Argument[2];logging;manual", - ";(String,Level,Object,Object[],Throwable);;Argument[2..3];logging;manual" - ], - jBossLogger() + ";true;" + ["debug", "error", "fatal", "info", "trace", "warn"] + ["f", "v"] - + - [ - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Object,Object,Object);;Argument[0..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];logging;manual", - ";(Throwable,String,Object);;Argument[1..2];logging;manual", - ";(Throwable,String,Object,Object);;Argument[1..3];logging;manual", - ";(Throwable,String,Object,Object,Object);;Argument[0..4];logging;manual" - ], - jBossLogger() + ";true;log" + ["f", "v"] + - [ - ";(Level,String,Object[]);;Argument[1..2];logging;manual", - ";(Level,String,Object);;Argument[1..2];logging;manual", - ";(Level,String,Object,Object);;Argument[1..3];logging;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];logging;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(Level,Throwable,String,Object);;Argument[2..3];logging;manual", - ";(Level,Throwable,String,Object,Object);;Argument[2..4];logging;manual", - ";(Level,Throwable,String,Object,Object,Object);;Argument[1..5];logging;manual", - ";(String,Level,Throwable,String,Object[]);;Argument[3..4];logging;manual", - ";(String,Level,Throwable,String,Object);;Argument[3..4];logging;manual", - ";(String,Level,Throwable,String,Object,Object);;Argument[3..5];logging;manual", - ";(String,Level,Throwable,String,Object,Object,Object);;Argument[3..6];logging;manual" - ], - // org.slf4j.spi.LoggingEventBuilder - "org.slf4j.spi;LoggingEventBuilder;true;log;;;Argument[0];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object);;Argument[0..1];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object[]);;Argument[0..1];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(String,Object,Object);;Argument[0..2];logging;manual", - "org.slf4j.spi;LoggingEventBuilder;true;log;(Supplier);;Argument[0];logging;manual", - // org.slf4j.Logger - "org.slf4j;Logger;true;" + ["debug", "error", "info", "trace", "warn"] + - [ - ";(String);;Argument[0];logging;manual", - ";(String,Object);;Argument[0..1];logging;manual", - ";(String,Object[]);;Argument[0..1];logging;manual", - ";(String,Object,Object);;Argument[0..2];logging;manual", - ";(String,Throwable);;Argument[0];logging;manual", - ";(Marker,String);;Argument[1];logging;manual", - ";(Marker,String,Object);;Argument[1..2];logging;manual", - ";(Marker,String,Object[]);;Argument[1..2];logging;manual", - ";(Marker,String,Object,Object);;Argument[1..3];logging;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];logging;manual" - ], - // org.scijava.Logger - "org.scijava.log;Logger;true;alwaysLog;(int,Object,Throwable);;Argument[1];logging;manual", - "org.scijava.log;Logger;true;" + ["debug", "error", "info", "trace", "warn"] + - [ - ";(Object);;Argument[0];logging;manual", - ";(Object,Throwable);;Argument[0];logging;manual" - ], "org.scijava.log;Logger;true;log;(int,Object);;Argument[1];logging;manual", - "org.scijava.log;Logger;true;log;(int,Object,Throwable);;Argument[1];logging;manual", - // com.google.common.flogger.LoggingApi - "com.google.common.flogger;LoggingApi;true;logVarargs;;;Argument[0..1];logging;manual", - "com.google.common.flogger;LoggingApi;true;log" + - [ - ";;;Argument[0];logging;manual", ";(String,Object);;Argument[1];logging;manual", - ";(String,Object,Object);;Argument[1..2];logging;manual", - ";(String,Object,Object,Object);;Argument[1..3];logging;manual", - ";(String,Object,Object,Object,Object);;Argument[1..4];logging;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[1..5];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[1..6];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..7];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];logging;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[]);;Argument[1..11];logging;manual", - ";(String,Object,boolean);;Argument[1];logging;manual", - ";(String,Object,char);;Argument[1];logging;manual", - ";(String,Object,byte);;Argument[1];logging;manual", - ";(String,Object,short);;Argument[1];logging;manual", - ";(String,Object,int);;Argument[1];logging;manual", - ";(String,Object,long);;Argument[1];logging;manual", - ";(String,Object,float);;Argument[1];logging;manual", - ";(String,Object,double);;Argument[1];logging;manual", - ";(String,boolean,Object);;Argument[2];logging;manual", - ";(String,char,Object);;Argument[2];logging;manual", - ";(String,byte,Object);;Argument[2];logging;manual", - ";(String,short,Object);;Argument[2];logging;manual", - ";(String,int,Object);;Argument[2];logging;manual", - ";(String,long,Object);;Argument[2];logging;manual", - ";(String,float,Object);;Argument[2];logging;manual", - ";(String,double,Object);;Argument[2];logging;manual" - ], - // java.lang.System$Logger - "java.lang;System$Logger;true;log;" + - [ - "(Level,Object);;Argument[1]", "(Level,String);;Argument[1]", - "(Level,String,Object[]);;Argument[1..2]", "(Level,String,Throwable);;Argument[1]", - "(Level,String,Supplier);;Argument[1..2]", - "(Level,String,Supplier,Throwable);;Argument[1..2]", - "(Level,ResourceBundle,String,Object[]);;Argument[2..3]", - "(Level,ResourceBundle,String,Throwable);;Argument[2]" - ] + ";logging;manual", - // java.util.logging.Logger - "java.util.logging;Logger;true;" + - ["config", "fine", "finer", "finest", "info", "severe", "warning"] + - ";;;Argument[0];logging;manual", - "java.util.logging;Logger;true;entering;(String,String);;Argument[0..1];logging;manual", - "java.util.logging;Logger;true;entering;(String,String,Object);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;entering;(String,String,Object[]);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;exiting;(String,String);;Argument[0..1];logging;manual", - "java.util.logging;Logger;true;exiting;(String,String,Object);;Argument[0..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Object);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Object[]);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;log;(Level,String,Throwable);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,Supplier);;Argument[1];logging;manual", - "java.util.logging;Logger;true;log;(Level,Throwable,Supplier);;Argument[2];logging;manual", - "java.util.logging;Logger;true;log;(LogRecord);;Argument[0];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Object);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Object[]);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,String,Throwable);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Supplier);;Argument[1..3];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logp;(Level,String,String,Throwable,Supplier);;Argument[4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Object[]);;Argument[4..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[1..2];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,ResourceBundle,String,Throwable);;Argument[4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String);;Argument[1..4];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object);;Argument[1..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Object[]);;Argument[1..5];logging;manual", - "java.util.logging;Logger;true;logrb;(Level,String,String,String,String,Throwable);;Argument[1..4];logging;manual", - // android.util.Log - "android.util;Log;true;" + ["d", "v", "i", "w", "e", "wtf"] + - ";;;Argument[1];logging;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll index af161760063..9622d7e50ba 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll @@ -53,9 +53,11 @@ class MockitoInitedTest extends Class { MockitoInitedTest() { // Tests run with the Mockito runner. exists(RunWithAnnotation a | a = this.getAnAncestor().getAnAnnotation() | + a.getRunner().(RefType).hasQualifiedName("org.mockito.junit", "MockitoJUnitRunner") + or + // Deprecated styles. a.getRunner().(RefType).hasQualifiedName("org.mockito.runners", "MockitoJUnitRunner") or - // Deprecated style. a.getRunner().(RefType).hasQualifiedName("org.mockito.runners", "MockitoJUnit44Runner") ) or diff --git a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll index 6c16bb168bb..4c1244ca1d5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll +++ b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll @@ -5,28 +5,12 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.TaintTracking -private import semmle.code.java.dataflow.ExternalFlow /** The class `org.apache.ibatis.jdbc.SqlRunner`. */ class MyBatisSqlRunner extends RefType { MyBatisSqlRunner() { this.hasQualifiedName("org.apache.ibatis.jdbc", "SqlRunner") } } -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.apache.ibatis.jdbc;SqlRunner;false;delete;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;insert;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;run;(String);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;selectAll;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;selectOne;(String,Object[]);;Argument[0];sql;manual", - "org.apache.ibatis.jdbc;SqlRunner;false;update;(String,Object[]);;Argument[0];sql;manual" - ] - } -} - /** The class `org.apache.ibatis.session.Configuration`. */ class IbatisConfiguration extends RefType { IbatisConfiguration() { this.hasQualifiedName("org.apache.ibatis.session", "Configuration") } @@ -144,74 +128,3 @@ private class MyBatisProviderStep extends TaintTracking::AdditionalValueStep { ) } } - -private class MyBatisAbstractSqlToStringStep extends SummaryModelCsv { - override predicate row(string row) { - row = "org.apache.ibatis.jdbc;AbstractSQL;true;toString;;;Argument[-1];ReturnValue;taint;manual" - } -} - -private class MyBatisAbstractSqlMethodsStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.ibatis.jdbc;AbstractSQL;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;WHERE;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;VALUES;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;UPDATE;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SET;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT_DISTINCT;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;SELECT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;RIGHT_OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;ORDER_BY;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OFFSET_ROWS;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;OFFSET;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LIMIT;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;LEFT_OUTER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INTO_VALUES;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INTO_COLUMNS;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INSERT_INTO;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;INNER_JOIN;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;HAVING;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;GROUP_BY;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FROM;(String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;FETCH_FIRST_ROWS_ONLY;(String);;Argument[0];Argument[-1];taint;manual", - "org.apache.ibatis.jdbc;AbstractSQL;true;DELETE_FROM;(String);;Argument[0];Argument[-1];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Objects.qll b/java/ql/lib/semmle/code/java/frameworks/Objects.qll deleted file mode 100644 index 1a7bbe8ef17..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Objects.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** Definitions of taint steps in Objects class of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ObjectsSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.util;Objects;false;requireNonNull;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElse;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElse;;;Argument[1];ReturnValue;value;manual", - "java.util;Objects;false;requireNonNullElseGet;;;Argument[0];ReturnValue;value;manual", - "java.util;Objects;false;toString;;;Argument[1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll b/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll deleted file mode 100644 index f541eb983ee..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/OkHttp.qll +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Provides classes and predicates for working with the OkHttp client. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class OkHttpOpenUrlSinks extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "okhttp3;Request;true;Request;;;Argument[0];open-url;manual", - "okhttp3;Request$Builder;true;url;;;Argument[0];open-url;manual" - ] - } -} - -private class OKHttpSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "okhttp3;HttpUrl;false;parse;;;Argument[0];ReturnValue;taint;manual", - "okhttp3;HttpUrl;false;uri;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl;false;url;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegments;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedPathSegments;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addEncodedQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegments;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addPathSegments;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;addQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;addQueryParameter;;;Argument[0..1];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedFragment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedFragment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedPassword;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedPath;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedPath;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedQuery;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;encodedQuery;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;encodedUsername;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;fragment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;fragment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;host;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;host;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;password;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;port;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;port;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;query;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;query;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;removeAllEncodedQueryParameters;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;removeAllQueryParameters;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;removePathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;scheme;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;scheme;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setEncodedQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setPathSegment;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setPathSegment;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;setQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "okhttp3;HttpUrl$Builder;false;setQueryParameter;;;Argument[0];Argument[-1];taint;manual", - "okhttp3;HttpUrl$Builder;false;username;;;Argument[-1];ReturnValue;value;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Optional.qll b/java/ql/lib/semmle/code/java/frameworks/Optional.qll deleted file mode 100644 index 7716154a883..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Optional.qll +++ /dev/null @@ -1,30 +0,0 @@ -/** Definitions related to `java.util.Optional`. */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class OptionalModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "java.util;Optional;false;filter;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Optional;false;filter;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;flatMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;flatMap;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;get;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;ifPresent;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;ifPresentOrElse;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;map;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util;Optional;false;map;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util;Optional;false;of;;;Argument[0];ReturnValue.Element;value;manual", - "java.util;Optional;false;ofNullable;;;Argument[0];ReturnValue.Element;value;manual", - "java.util;Optional;false;or;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util;Optional;false;or;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;orElse;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;orElse;;;Argument[0];ReturnValue;value;manual", - "java.util;Optional;false;orElseGet;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;orElseGet;;;Argument[0].ReturnValue;ReturnValue;value;manual", - "java.util;Optional;false;orElseThrow;;;Argument[-1].Element;ReturnValue;value;manual", - "java.util;Optional;false;stream;;;Argument[-1].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Properties.qll b/java/ql/lib/semmle/code/java/frameworks/Properties.qll index 0c7b83b2e52..096e3bbb43c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Properties.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Properties.qll @@ -1,4 +1,5 @@ -/* Definitions related to `java.util.Properties`. */ +/** Definitions related to `java.util.Properties`. */ + import semmle.code.java.Type private import semmle.code.java.dataflow.FlowSteps diff --git a/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll b/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll deleted file mode 100644 index 4f94cd295a8..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Provides classes and predicates related to RabbitMQ. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Defines remote sources in RabbitMQ. - */ -private class RabbitMQSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // soruces for RabbitMQ 4.x - "com.rabbitmq.client;Command;true;getContentHeader;();;ReturnValue;remote;manual", - "com.rabbitmq.client;Command;true;getContentBody;();;ReturnValue;remote;manual", - "com.rabbitmq.client;Consumer;true;handleDelivery;(String,Envelope,BasicProperties,byte[]);;Parameter[3];remote;manual", - "com.rabbitmq.client;QueueingConsumer;true;nextDelivery;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(Delivery,BasicProperties);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(BasicProperties,byte[],BasicProperties);;Parameter[1];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCall;(byte[],BasicProperties);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;preprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;postprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(Delivery);;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(BasicProperties,byte[]);;Parameter[1];remote;manual", - "com.rabbitmq.client;RpcServer;true;handleCast;(byte[]);;Parameter[0];remote;manual", - "com.rabbitmq.client;StringRpcServer;true;handleStringCall;;;Parameter[0];remote;manual", - "com.rabbitmq.client;RpcClient;true;doCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;primitiveCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;responseCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;stringCall;(String);;ReturnValue;remote;manual", - "com.rabbitmq.client;RpcClient;true;mapCall;;;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;Frame;true;getInputStream;();;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;Frame;true;getPayload;();;ReturnValue;remote;manual", - "com.rabbitmq.client.impl;FrameHandler;true;readFrame;();;ReturnValue;remote;manual", - ] - } -} - -/** - * Defines flow steps in RabbitMQ. - */ -private class RabbitMQSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - // flow steps for RabbitMQ 4.x - "com.rabbitmq.client;GetResponse;true;GetResponse;;;Argument[2];Argument[-1];taint;manual", - "com.rabbitmq.client;GetResponse;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client;RpcClient$Response;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client;QueueingConsumer$Delivery;true;getBody;();;Argument[-1];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;false;fromBodyFragment;(int,byte[],int,int);;Argument[1];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;false;readFrom;(DataInputStream);;Argument[0];ReturnValue;taint;manual", - "com.rabbitmq.client.impl;Frame;true;writeTo;(DataOutputStream);;Argument[-1];Argument[0];taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Regex.qll b/java/ql/lib/semmle/code/java/frameworks/Regex.qll index 4e83981d857..780dec48b92 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Regex.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Regex.qll @@ -1,20 +1,24 @@ /** Definitions related to `java.util.regex`. */ -private import semmle.code.java.dataflow.ExternalFlow +import java -private class RegexModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.util.regex;Matcher;false;group;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "java.util.regex;Matcher;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;matcher;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;quote;;;Argument[0];ReturnValue;taint;manual", - "java.util.regex;Pattern;false;split;;;Argument[0];ReturnValue;taint;manual", - ] +/** The class `java.util.regex.Pattern`. */ +class TypeRegexPattern extends Class { + TypeRegexPattern() { this.hasQualifiedName("java.util.regex", "Pattern") } +} + +/** The `quote` method of the `java.util.regex.Pattern` class. */ +class PatternQuoteMethod extends Method { + PatternQuoteMethod() { + this.getDeclaringType() instanceof TypeRegexPattern and + this.hasName("quote") + } +} + +/** The `LITERAL` field of the `java.util.regex.Pattern` class. */ +class PatternLiteralField extends Field { + PatternLiteralField() { + this.getDeclaringType() instanceof TypeRegexPattern and + this.hasName("LITERAL") } } diff --git a/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll b/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll deleted file mode 100644 index db79cb84515..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Retrofit.qll +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Provides classes and predicates for working with the Retrofit API client. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class RetrofitOpenUrlSinks extends SinkModelCsv { - override predicate row(string row) { - row = "retrofit2;Retrofit$Builder;true;baseUrl;;;Argument[0];open-url;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll index 19428afae92..3b96ccd828d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll @@ -1,4 +1,5 @@ -/* Remote Method Invocation. */ +/** Remote Method Invocation. */ + import java /** The interface `java.rmi.Remote`. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll index f0a75c8f3b9..82eedca44e8 100644 --- a/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll +++ b/java/ql/lib/semmle/code/java/frameworks/SpringJdbc.qll @@ -3,51 +3,8 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The class `org.springframework.jdbc.core.JdbcTemplate`. */ class JdbcTemplate extends RefType { JdbcTemplate() { this.hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") } } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;(String[]);;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;execute;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;update;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;query;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForList;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql;manual", - "org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql;manual", - "org.springframework.jdbc.object;BatchSqlUpdate;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;MappingSqlQuery;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;MappingSqlQueryWithParameters;false;BatchSqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;RdbmsOperation;true;setSql;;;Argument[0];sql;manual", - "org.springframework.jdbc.object;SqlCall;false;SqlCall;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlFunction;false;SqlFunction;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlQuery;false;SqlQuery;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;SqlUpdate;false;SqlUpdate;;;Argument[1];sql;manual", - "org.springframework.jdbc.object;UpdatableSqlQuery;false;UpdatableSqlQuery;;;Argument[1];sql;manual" - ] - } -} - -private class SsrfSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "org.springframework.boot.jdbc;DataSourceBuilder;false;url;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;AbstractDriverBasedDataSource;false;setUrl;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,String,String);;Argument[0];jdbc-url;manual", - "org.springframework.jdbc.datasource;DriverManagerDataSource;false;DriverManagerDataSource;(String,Properties);;Argument[0];jdbc-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Stream.qll b/java/ql/lib/semmle/code/java/frameworks/Stream.qll index 0c1347044c5..f68cd6c844e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Stream.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Stream.qll @@ -1,6 +1,5 @@ /** Definitions related to `java.util.stream`. */ -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSummary private class CollectCall extends MethodAccess { @@ -96,95 +95,3 @@ private class RequiredComponentStackForCollect extends RequiredSummaryComponentS tail = SummaryComponentStack::return() } } - -private class StreamModel extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "java.util.stream;BaseStream;true;iterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;onClose;(Runnable);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;parallel;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;sequential;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;spliterator;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;BaseStream;true;unordered;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;allMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;anyMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[1].Parameter[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[1].Parameter[0];Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[2].Parameter[0..1];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[-1].Element;Argument[1].Parameter[1];value;manual", - // collect(Collector collector) is handled separately on a case-by-case basis as it is too complex for MaD - "java.util.stream;Stream;true;concat;(Stream,Stream);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;distinct;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;dropWhile;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;dropWhile;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;filter;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;filter;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;findAny;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;findFirst;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;flatMap;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;flatMapToDouble;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMapToInt;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;flatMapToLong;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;forEach;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;forEachOrdered;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[0];Argument[1..2].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[2].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,Predicate,UnaryOperator);;Argument[2].ReturnValue;Argument[1..2].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;limit;(long);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;map;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - // Missing for mapMulti(BiConsumer) (not currently supported): - // Argument[0] of Parameter[1] of Argument[0] -> Element of Parameter[1] of Argument[0] - // Element of Parameter[1] of Argument[0] -> Element of ReturnValue - "java.util.stream;Stream;true;mapMulti;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToDouble;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToInt;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapMultiToLong;(BiConsumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToInt;(ToIntFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;mapToLong;(ToLongFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;max;(Comparator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;max;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;min;(Comparator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;min;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;noneMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;ofNullable;(Object);;Argument[0];ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;peek;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;peek;(Consumer);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;Argument[1].Parameter[0];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;Argument[2].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1..2].ReturnValue;ReturnValue;value;manual", - "java.util.stream;Stream;true;skip;(long);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;sorted;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;sorted;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0..1];value;manual", - "java.util.stream;Stream;true;takeWhile;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "java.util.stream;Stream;true;takeWhile;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;manual", - "java.util.stream;Stream;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "java.util.stream;Stream;true;toList;();;Argument[-1].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Strings.qll b/java/ql/lib/semmle/code/java/frameworks/Strings.qll deleted file mode 100644 index c09b959254d..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Strings.qll +++ /dev/null @@ -1,70 +0,0 @@ -/** Definitions of taint steps in String and String-related classes of the JDK */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StringSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "java.lang;String;false;concat;(String);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;concat;(String);;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;copyValueOf;;;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;endsWith;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;format;(Locale,String,Object[]);;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;format;(Locale,String,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;manual", - "java.lang;String;false;format;(String,Object[]);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;format;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "java.lang;String;false;formatted;(Object[]);;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;formatted;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "java.lang;String;false;getChars;;;Argument[-1];Argument[2];taint;manual", - "java.lang;String;false;getBytes;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;getBytes;;;Argument[-1];Argument[2];taint;manual", - "java.lang;String;false;indent;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;intern;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;join;;;Argument[0..1];ReturnValue;taint;manual", - "java.lang;String;false;repeat;(int);;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;replace;;;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;replaceAll;;;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;replaceFirst;;;Argument[1];ReturnValue;taint;manual", - "java.lang;String;false;split;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;String;;;Argument[0];Argument[-1];taint;manual", - "java.lang;String;false;strip;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;stripIndent;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;stripLeading;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;stripTrailing;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toLowerCase;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;toString;;;Argument[-1];ReturnValue;value;manual", - "java.lang;String;false;toUpperCase;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;translateEscapes;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;trim;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "java.lang;String;false;valueOf;(char[]);;Argument[0];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;AbstractStringBuilder;(String);;Argument[0];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;append;;;Argument[0];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;append;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;getChars;;;Argument[-1];Argument[2];taint;manual", - "java.lang;AbstractStringBuilder;true;insert;;;Argument[1];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;insert;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;replace;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;replace;;;Argument[2];Argument[-1];taint;manual", - "java.lang;AbstractStringBuilder;true;reverse;;;Argument[-1];ReturnValue;value;manual", - "java.lang;AbstractStringBuilder;true;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;substring;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;AbstractStringBuilder;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;StringBuffer;true;StringBuffer;(CharSequence);;Argument[0];Argument[-1];taint;manual", - "java.lang;StringBuffer;true;StringBuffer;(String);;Argument[0];Argument[-1];taint;manual", - "java.lang;StringBuilder;true;StringBuilder;;;Argument[0];Argument[-1];taint;manual", - "java.lang;CharSequence;true;charAt;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;CharSequence;true;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "java.lang;CharSequence;true;toString;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll b/java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll deleted file mode 100644 index 3c550d5441c..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/Thymeleaf.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides classes and predicates for working with the Thymeleaf template engine. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ThymeleafSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.thymeleaf;TemplateSpec;false;TemplateSpec;;;Argument[0];Argument[-1];taint;manual", - "org.thymeleaf;TemplateSpec;false;getTemplate;;;Argument[-1];ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Android.qll b/java/ql/lib/semmle/code/java/frameworks/android/Android.qll index 30f087408af..1a992eb5565 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Android.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Android.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.xml.AndroidManifest /** @@ -27,7 +26,12 @@ class AndroidComponent extends Class { /** The XML element corresponding to this Android component. */ AndroidComponentXmlElement getAndroidComponentXmlElement() { - result.getResolvedComponentName() = this.getQualifiedName() + // Find an element with an identifier matching the qualified name of the component. + // Aliases have two identifiers (name and target), so check both identifiers (if present). + exists(AndroidIdentifierXmlAttribute identifier | + identifier = result.getAnAttribute() and + result.getResolvedIdentifier(identifier) = this.getQualifiedName() + ) } /** Holds if this Android component is configured as `exported` in an `AndroidManifest.xml` file. */ @@ -53,6 +57,12 @@ class ExportableAndroidComponent extends AndroidComponent { or this.hasIntentFilter() and not this.getAndroidComponentXmlElement().isNotExported() + or + exists(AndroidActivityAliasXmlElement e | + e = this.getAndroidComponentXmlElement() and + not e.isNotExported() and + e.hasAnIntentFilterElement() + ) } } @@ -103,74 +113,6 @@ class AndroidContentResolver extends AndroidComponent { } } -private class UriModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.net;Uri;true;buildUpon;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;decode;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;encode;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;fromFile;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;false;fromParts;;;Argument[0..2];ReturnValue;taint;manual", - "android.net;Uri;true;getAuthority;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedAuthority;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedFragment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedPath;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedQuery;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getEncodedUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getFragment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getHost;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getLastPathSegment;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getPath;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQuery;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameterNames;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getQueryParameters;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getScheme;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;getUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;true;normalizeScheme;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;parse;;;Argument[0];ReturnValue;taint;manual", - "android.net;Uri;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri;false;withAppendedPath;;;Argument[0..1];ReturnValue;taint;manual", - "android.net;Uri;false;writeToParcel;;;Argument[1];Argument[0];taint;manual", - "android.net;Uri$Builder;false;appendEncodedPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendEncodedPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;appendPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;appendQueryParameter;;;Argument[0..1];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;appendQueryParameter;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;authority;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;authority;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "android.net;Uri$Builder;false;clearQuery;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedAuthority;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedAuthority;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedFragment;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedFragment;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedOpaquePart;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedOpaquePart;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedPath;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedPath;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;encodedQuery;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;encodedQuery;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;fragment;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;fragment;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;opaquePart;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;opaquePart;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;path;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;path;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;query;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;query;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;scheme;;;Argument[0];Argument[-1];taint;manual", - "android.net;Uri$Builder;false;scheme;;;Argument[-1];ReturnValue;value;manual", - "android.net;Uri$Builder;false;toString;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - /** Interface for classes whose instances can be written to and restored from a Parcel. */ class TypeParcelable extends Interface { TypeParcelable() { this.hasQualifiedName("android.os", "Parcelable") } @@ -185,29 +127,3 @@ class CreateFromParcelMethod extends Method { this.getEnclosingCallable().getDeclaringType().getAnAncestor() instanceof TypeParcelable } } - -private class ParcelPropagationModels extends SummaryModelCsv { - override predicate row(string s) { - // Parcel readers that return their value - s = - "android.os;Parcel;false;read" + - [ - "Array", "ArrayList", "Boolean", "Bundle", "Byte", "Double", "FileDescriptor", "Float", - "HashMap", "Int", "Long", "Parcelable", "ParcelableArray", "PersistableBundle", - "Serializable", "Size", "SizeF", "SparseArray", "SparseBooleanArray", "String", - "StrongBinder", "TypedObject", "Value" - ] + ";;;Argument[-1];ReturnValue;taint;manual" - or - // Parcel readers that write to an existing object - s = - "android.os;Parcel;false;read" + - [ - "BinderArray", "BinderList", "BooleanArray", "ByteArray", "CharArray", "DoubleArray", - "FloatArray", "IntArray", "List", "LongArray", "Map", "ParcelableList", "StringArray", - "StringList", "TypedArray", "TypedList" - ] + ";;;Argument[-1];Argument[0];taint;manual" - or - // One Parcel method that aliases an argument to a return value - s = "android.os;Parcel;false;readParcelableList;;;Argument[0];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll index 1e10a01d451..7bcd4baa3e5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ContentProviders.qll @@ -3,114 +3,8 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The class `android.content.ContentValues`. */ class ContentValues extends Class { ContentValues() { this.hasQualifiedName("android.content", "ContentValues") } } - -private class ContentProviderSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - // ContentInterface models are here for backwards compatibility (it was removed in API 28) - "android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider;manual", - "android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider;manual", - "android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider;manual", - "android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider;manual", - "android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider;manual", - "android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider;manual", - "android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider;manual", - "android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider;manual", - "android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider;manual", - "android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider;manual" - ] - } -} - -private class SummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.content;ContentValues;false;put;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.content;ContentValues;false;put;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.content;ContentValues;false;putAll;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.content;ContentResolver;true;acquireContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;applyBatch;;;Argument[1];ReturnValue;taint;manual", - "android.content;ContentResolver;true;call;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;canonicalize;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;getStreamTypes;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;getType;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;insert;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;uncanonicalize;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;wrap;;;Argument[0];ReturnValue;taint;manual", - // ContentProviderClient is tainted at its creation, not by its arguments - "android.content;ContentProviderClient;true;applyBatch;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;call;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;canonicalize;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;getLocalContentProvider;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;getStreamTypes;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;insert;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;query;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderClient;true;uncanonicalize;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;apply;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;apply;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;getUri;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newAssertQuery;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newCall;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newDelete;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newInsert;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;newUpdate;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveExtrasBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveSelectionArgsBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation;false;resolveValueBackReferences;;;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProviderOperation$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ContentProviderOperation$Builder;false;withExceptionAllowed;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExpectedCount;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtraBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withExtras;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withSelection;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withSelectionBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValue;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValueBackReference;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withValues;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderOperation$Builder;false;withYieldAllowed;;;Argument[-1];ReturnValue;value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Uri);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.uri];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Bundle);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.extras];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Throwable);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.exception];value;manual", - "android.content;ContentProviderResult;false;ContentProviderResult;(Parcel);;Argument[0];Argument[-1];taint;manual", - "android.database;Cursor;true;copyStringToBuffer;;;Argument[-1];Argument[1];taint;manual", - "android.database;Cursor;true;getBlob;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getColumnName;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getColumnNames;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getExtras;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getNotificationUri;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getNotificationUris;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;getString;;;Argument[-1];ReturnValue;taint;manual", - "android.database;Cursor;true;respond;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index 1e6919c023b..7eb088a9514 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -5,21 +5,6 @@ private import semmle.code.java.security.FileReadWrite private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow -private class ExternalStorageDirSourceModel extends SourceModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalCacheDir;();;ReturnValue;android-external-storage-dir;manual", - "android.content;Context;true;getExternalCacheDirs;();;ReturnValue;android-external-storage-dir;manual", - "android.os;Environment;false;getExternalStorageDirectory;();;ReturnValue;android-external-storage-dir;manual", - "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue;android-external-storage-dir;manual", - ] - } -} - private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node node2) { DataFlow::localFlowStep(node1, node2) or diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll index e37e7f350b8..4f6e9e3f5e4 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll @@ -421,196 +421,3 @@ private class StartServiceIntentStep extends AdditionalValueStep { ) } } - -private class IntentBundleFlowSteps extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"namespace;type;subtypes;name;signature;ext;input;output;kind" - "android.os;BaseBundle;true;get;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;getString;(String,String);;Argument[1];ReturnValue;value;manual", - "android.os;BaseBundle;true;getStringArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;BaseBundle;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "android.os;BaseBundle;true;putAll;(PersistableBundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putAll;(PersistableBundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;BaseBundle;true;putBoolean;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putBooleanArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putDouble;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putDoubleArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putInt;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putIntArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putLong;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putLongArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putString;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putString;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;BaseBundle;true;putStringArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;BaseBundle;true;putStringArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;false;Bundle;(Bundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;false;Bundle;(Bundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;false;Bundle;(PersistableBundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;false;Bundle;(PersistableBundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;clone;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "android.os;Bundle;true;clone;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - // model for Bundle.deepCopy is not fully precise, as some map values aren't copied by value - "android.os;Bundle;true;deepCopy;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "android.os;Bundle;true;deepCopy;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "android.os;Bundle;true;getBinder;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getBundle;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getByteArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String,CharSequence);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequence;(String,CharSequence);;Argument[1];ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequenceArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getCharSequenceArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelable;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelableArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getParcelableArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getSerializable;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getSparseParcelableArray;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;getStringArrayList;(String);;Argument[-1].MapValue;ReturnValue;value;manual", - "android.os;Bundle;true;putAll;(Bundle);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putAll;(Bundle);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putBinder;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putBinder;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putBundle;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putBundle;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putByte;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putByteArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putByteArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putChar;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequence;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequence;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequenceArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequenceArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putCharSequenceArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putCharSequenceArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putFloat;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putFloatArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putIntegerArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelable;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelable;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putParcelableArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelableArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putParcelableArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putParcelableArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putSerializable;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSerializable;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putShort;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putShortArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSize;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSizeF;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSparseParcelableArray;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putSparseParcelableArray;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;putStringArrayList;;;Argument[0];Argument[-1].MapKey;value;manual", - "android.os;Bundle;true;putStringArrayList;;;Argument[1];Argument[-1].MapValue;value;manual", - "android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapKey;taint;manual", - "android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapValue;taint;manual", - // currently only the Extras part of the intent and the data field are fully modeled - "android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;false;Intent;(String,Uri);;Argument[1];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;false;Intent;(String,Uri,Context,Class);;Argument[1];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;addCategory;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;addFlags;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;false;createChooser;;;Argument[0..2];ReturnValue.SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;getBundleExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getByteArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getCharSequenceExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getData;;;Argument[-1].SyntheticField[android.content.Intent.data];ReturnValue;value;manual", - "android.content;Intent;true;getDataString;;;Argument[-1].SyntheticField[android.content.Intent.data];ReturnValue;taint;manual", - "android.content;Intent;true;getExtras;();;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.content;Intent;false;getIntent;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;false;getIntentOld;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;true;getParcelableArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getParcelableArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getParcelableExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getSerializableExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringArrayExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringArrayListExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;true;getStringExtra;(String);;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;ReturnValue;value;manual", - "android.content;Intent;false;parseUri;;;Argument[0];ReturnValue.SyntheticField[android.content.Intent.data];taint;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putCharSequenceArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtras;(Bundle);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putExtras;(Intent);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putIntegerArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putIntegerArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putParcelableArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[1];Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;putStringArrayListExtra;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;replaceExtras;(Bundle);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.content;Intent;true;replaceExtras;(Intent);;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setAction;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setClass;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setClassName;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setComponent;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setData;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setData;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndNormalize;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndNormalize;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndType;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndType;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setDataAndTypeAndNormalize;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setDataAndTypeAndNormalize;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.data];value;manual", - "android.content;Intent;true;setFlags;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setIdentifier;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setPackage;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setType;;;Argument[-1];ReturnValue;value;manual", - "android.content;Intent;true;setTypeAndNormalize;;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class IntentComponentTaintSteps extends SummaryModelCsv { - override predicate row(string s) { - s = - [ - "android.content;Intent;true;Intent;(Intent);;Argument[0];Argument[-1];taint;manual", - "android.content;Intent;true;Intent;(Context,Class);;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;Intent;(String,Uri,Context,Class);;Argument[3];Argument[-1];taint;manual", - "android.content;Intent;true;getIntent;(String);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;getIntentOld;(String);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;parseUri;(String,int);;Argument[0];ReturnValue;taint;manual", - "android.content;Intent;true;setPackage;;;Argument[0];Argument[-1];taint;manual", - "android.content;Intent;true;setClass;;;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;setClassName;(Context,String);;Argument[1];Argument[-1];taint;manual", - "android.content;Intent;true;setClassName;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "android.content;Intent;true;setComponent;;;Argument[0];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Context,String);;Argument[1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Context,Class);;Argument[1];Argument[-1];taint;manual", - "android.content;ComponentName;false;ComponentName;(Parcel);;Argument[0];Argument[-1];taint;manual", - "android.content;ComponentName;false;createRelative;(String,String);;Argument[0..1];ReturnValue;taint;manual", - "android.content;ComponentName;false;createRelative;(Context,String);;Argument[1];ReturnValue;taint;manual", - "android.content;ComponentName;false;flattenToShortString;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;flattenToString;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getClassName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getPackageName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;getShortClassName;;;Argument[-1];ReturnValue;taint;manual", - "android.content;ComponentName;false;unflattenFromString;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll b/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll deleted file mode 100644 index 0f69f0bbe1d..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll +++ /dev/null @@ -1,101 +0,0 @@ -/** Provides classes and predicates related to Android notifications. */ - -import java -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.FlowSteps - -private class NotificationBuildersSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.app;Notification$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;Builder;(Icon,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.app;Notification$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.app;Notification$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", - "android.app;Notification$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action;true;Action;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", - "androidx.core.app;NotificationCompat$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "android.app;Notification$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "android.app;Notification$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual", - "android.app;Notification$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "android.app;Notification$Builder;true;recoverBuilder;;;Argument[1];ReturnValue;taint;manual", - "android.app;Notification$Builder;true;setActions;;;Argument[0].ArrayElement;Argument[-1];taint;manual", - "android.app;Notification$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", - "android.app;Notification$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", - "androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", - "androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$Style;true;build;;;Argument[-1];ReturnValue;taint;manual", - "android.app;Notification$BigPictureStyle;true;BigPictureStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$BigTextStyle;true;BigTextStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$InboxStyle;true;InboxStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - "android.app;Notification$MediaStyle;true;MediaStyle;(Builder);;Argument[0];Argument[-1];taint;manual", - // Fluent models - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + - "$Action$Builder;true;" + - [ - "addExtras", "addRemoteInput", "extend", "setAllowGeneratedReplies", - "setAuthenticationRequired", "setContextual", "setSemanticAction" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$Builder;true;" + - [ - "addAction", "addExtras", "addPerson", "extend", "setActions", "setAutoCancel", - "setBadgeIconType", "setBubbleMetadata", "setCategory", "setChannelId", - "setChronometerCountDown", "setColor", "setColorized", "setContent", "setContentInfo", - "setContentIntent", "setContentText", "setContentTitle", "setCustomBigContentView", - "setCustomHeadsUpContentView", "setDefaults", "setDeleteIntent", "setExtras", "setFlag", - "setForegroundServiceBehavior", "setFullScreenIntent", "setGroup", - "setGroupAlertBehavior", "setGroupSummary", "setLargeIcon", "setLights", "setLocalOnly", - "setLocusId", "setNumber", "setOngoing", "setOnlyAlertOnce", "setPriority", - "setProgress", "setPublicVersion", "setRemoteInputHistory", "setSettingsText", - "setShortcutId", "setShowWhen", "setSmallIcon", "setSortKey", "setSound", "setStyle", - "setSubText", "setTicker", "setTimeoutAfter", "setUsesChronometer", "setVibrate", - "setVisibility", "setWhen" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + - "$BigPictureStyle;true;" + - [ - "bigLargeIcon", "bigPicture", "setBigContentTitle", "setContentDescription", - "setSummaryText", "showBigPictureWhenCollapsed" - ] + ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$BigTextStyle;true;" - + ["bigText", "setBigContentTitle", "setSummaryText"] + - ";;;Argument[-1];ReturnValue;value;manual", - ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$InboxStyle;true;" + - ["addLine", "setBigContentTitle", "setSummaryText"] + - ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$MediaStyle;true;" + - ["setMediaSession", "setShowActionsInCompactView"] + - ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll b/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll index 5f1c1b19171..2898b6aee54 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/SQLite.qll @@ -1,7 +1,6 @@ /** Provides classes and predicates for working with SQLite databases. */ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.frameworks.android.Android @@ -41,138 +40,3 @@ class TypeSQLiteOpenHelper extends Class { class TypeSQLiteStatement extends Class { TypeSQLiteStatement() { this.hasQualifiedName("android.database.sqlite", "SQLiteStatement") } } - -private class SQLiteSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;spec;kind" - "android.database.sqlite;SQLiteDatabase;false;compileStatement;(String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execSQL;(String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execSQL;(String,Object[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;execPerConnectionSQL;(String,Object[]);;Argument[0];sql;manual", - // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) - // query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) - // queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) - // queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) - // Each String / String[] arg except for selectionArgs is a sink - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[4..7];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[0..2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[4..6];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[5..8];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[5..8];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[4];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[6..9];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[6..9];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[],CancellationSignal);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;delete;(String,String,String[]);;Argument[0..1];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[0];sql;manual", - "android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[2];sql;manual", - "android.database;DatabaseUtils;false;longForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;stringForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;blobFileDescriptorForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;createDbFromSqlStatements;(Context,String,int,String);;Argument[3];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String);;Argument[1];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String);;Argument[1..2];sql;manual", - "android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String,String[]);;Argument[1..2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;insert;(SQLiteDatabase,ContentValues);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[2];sql;manual", - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder) - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) - // query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal) - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[4..6];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[4..7];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[-1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4..7];sql;manual", - "android.content;ContentProvider;true;delete;(Uri,String,String[]);;Argument[1];sql;manual", - "android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[2];sql;manual", - "android.content;ContentResolver;true;delete;(Uri,String,String[]);;Argument[1];sql;manual", - "android.content;ContentResolver;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[2];sql;manual" - ] - } -} - -private class SqlFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - // buildQuery(String[] projectionIn, String selection, String groupBy, String having, String sortOrder, String limit) - // buildQuery(String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) - // buildUnionQuery(String[] subQueries, String sortOrder, String limit) - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[1..5];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[3..6];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[-1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[1..2];ReturnValue;taint;manual", - // buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String[] selectionArgs, String groupBy, String having) - // buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String groupBy, String having) - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[-1..0];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[2].Element;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[4..5];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[7..8];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[-1..0];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[2].Element;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[4..7];ReturnValue;taint;manual", - // static buildQueryString(boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit) - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[1];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[2].ArrayElement;ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[3..7];ReturnValue;taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;Argument[0].MapKey;Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;setTables;(String);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendWhere;(CharSequence);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendWhereStandalone;(CharSequence);;Argument[0];Argument[-1];taint;manual", - "android.database.sqlite;SQLiteQueryBuilder;true;appendColumns;(StringBuilder,String[]);;Argument[1].ArrayElement;Argument[0];taint;manual", - "android.database;DatabaseUtils;false;appendSelectionArgs;(String[],String[]);;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "android.database;DatabaseUtils;false;concatenateWhere;(String,String);;Argument[0..1];ReturnValue;taint;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint;manual", - "android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll b/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll index 8a5c455fedd..a3298fd70d8 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/SharedPreferences.qll @@ -1,7 +1,6 @@ /** Provides classes related to `android.content.SharedPreferences`. */ import java -private import semmle.code.java.dataflow.ExternalFlow /** The interface `android.content.SharedPreferences`. */ class SharedPreferences extends Interface { @@ -56,19 +55,3 @@ class StoreSharedPreferenceMethod extends Method { this.hasName(["commit", "apply"]) } } - -private class SharedPreferencesSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "android.content;SharedPreferences$Editor;true;clear;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putBoolean;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putFloat;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putInt;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putLong;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putString;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;putStringSet;;;Argument[-1];ReturnValue;value;manual", - "android.content;SharedPreferences$Editor;true;remove;;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll index b787f0ad282..33de1ea0d12 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Slice.qll @@ -3,7 +3,6 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow /** The class `androidx.slice.SliceProvider`. */ class SliceProvider extends Class { @@ -39,87 +38,3 @@ private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent, TaintInheritingContent { SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" } } - -private class SliceBuildersSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice.builders;ListBuilder;true;addAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addGridRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addInputRange;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRange;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRating;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;addSelection;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setHeader;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setSeeMoreAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;setSeeMoreRow;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder;true;build;;;Argument[-1].SyntheticField[androidx.slice.Slice.action];ReturnValue;taint;manual", - "androidx.slice.builders;ListBuilder$HeaderBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;addEndItem;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;setInputAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RangeBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;setInputAction;(PendingIntent);;Argument[0];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;addEndItem;(SliceAction,boolean);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;addEndItem;(SliceAction);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setPrimaryAction;;;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setTitleItem;(SliceAction,boolean);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;setTitleItem;(SliceAction);;Argument[0].SyntheticField[androidx.slice.Slice.action];Argument[-1].SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;create;(PendingIntent,IconCompat,int,CharSequence);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;createDeeplink;(PendingIntent,IconCompat,int,CharSequence);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;createToggle;(PendingIntent,CharSequence,boolean);;Argument[0];ReturnValue.SyntheticField[androidx.slice.Slice.action];taint;manual", - "androidx.slice.builders;SliceAction;true;getAction;;;Argument[-1].SyntheticField[androidx.slice.Slice.action];ReturnValue;taint;manual", - // Fluent models - "androidx.slice.builders;ListBuilder;true;" + - [ - "addAction", "addGridRow", "addInputRange", "addRange", "addRating", "addRow", - "addSelection", "setAccentColor", "setHeader", "setHostExtras", "setIsError", - "setKeywords", "setLayoutDirection", "setSeeMoreAction", "setSeeMoreRow" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$HeaderBuilder;true;" + - [ - "setContentDescription", "setLayoutDirection", "setPrimaryAction", "setSubtitle", - "setSummary", "setTitle" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$InputRangeBuilder;true;" + - [ - "addEndItem", "setContentDescription", "setInputAction", "setLayoutDirection", "setMax", - "setMin", "setPrimaryAction", "setSubtitle", "setThumb", "setTitle", "setTitleItem", - "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RangeBuilder;true;" + - [ - "setContentDescription", "setMax", "setMode", "setPrimaryAction", "setSubtitle", - "setTitle", "setTitleItem", "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RatingBuilder;true;" + - [ - "setContentDescription", "setInputAction", "setMax", "setMin", "setPrimaryAction", - "setSubtitle", "setTitle", "setTitleItem", "setValue" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;ListBuilder$RowBuilder;true;" + - [ - "addEndItem", "setContentDescription", "setEndOfSection", "setLayoutDirection", - "setPrimaryAction", "setSubtitle", "setTitle", "setTitleItem" - ] + ";;;Argument[-1];ReturnValue;value;manual", - "androidx.slice.builders;SliceAction;true;" + - ["setChecked", "setContentDescription", "setPriority"] + - ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} - -private class SliceProviderSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice;SliceProvider;true;onBindSlice;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onCreatePermissionRequest;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onMapIntentToUri;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onSlicePinned;;;Parameter[0];contentprovider;manual", - "androidx.slice;SliceProvider;true;onSliceUnpinned;;;Parameter[0];contentprovider;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll b/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll index 8dd91f73f65..b514ca94be7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/WebView.qll @@ -45,7 +45,10 @@ class WebViewGetUrlMethod extends Method { class CrossOriginAccessMethod extends Method { CrossOriginAccessMethod() { this.getDeclaringType() instanceof TypeWebSettings and - this.hasName(["setAllowUniversalAccessFromFileURLs", "setAllowFileAccessFromFileURLs"]) + this.hasName([ + "setAllowFileAccess", "setAllowUniversalAccessFromFileURLs", + "setAllowFileAccessFromFileURLs" + ]) } } diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll index e66852e8e2e..81c34179c15 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll @@ -4,12 +4,6 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources -private class AndroidWidgetSourceModels extends SourceModelCsv { - override predicate row(string row) { - row = "android.widget;EditText;true;getText;;;ReturnValue;android-widget;manual" - } -} - private class DefaultAndroidWidgetSources extends RemoteFlowSource { DefaultAndroidWidgetSources() { sourceNode(this, "android-widget") } @@ -35,9 +29,3 @@ private class EditableToStringStep extends AdditionalTaintStep { ) } } - -private class AndroidWidgetSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = "android.widget;EditText;true;getText;;;Argument[-1];ReturnValue;taint;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll b/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll deleted file mode 100644 index c324d22a605..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/android/XssSinks.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** Provides XSS sink models relating to the `android.webkit.WebView` class. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** CSV sink models representing methods susceptible to XSS attacks. */ -private class DefaultXssSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "android.webkit;WebView;false;loadData;;;Argument[0];xss;manual", - "android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss;manual", - "android.webkit;WebView;false;evaluateJavascript;;;Argument[0];xss;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll index 4eb7f644233..24030e35045 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Collections.qll @@ -2,7 +2,6 @@ import java private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow /** * The method `isEmpty` in either `org.apache.commons.collections.CollectionUtils` @@ -29,1163 +28,3 @@ class MethodApacheCollectionsIsNotEmpty extends Method { this.hasName("isNotEmpty") } } - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4`. - */ -private class ApacheCollectionsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should model things relating to Closure, Factory, Transformer, FluentIterable.forEach, FluentIterable.transform - ";ArrayStack;true;peek;;;Argument[-1].Element;ReturnValue;value;manual", - ";ArrayStack;true;pop;;;Argument[-1].Element;ReturnValue;value;manual", - ";ArrayStack;true;push;;;Argument[0];Argument[-1].Element;value;manual", - ";ArrayStack;true;push;;;Argument[0];ReturnValue;value;manual", - ";Bag;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ";Bag;true;uniqueSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";BidiMap;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";BidiMap;true;removeValue;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";BidiMap;true;inverseBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ";BidiMap;true;inverseBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ";FluentIterable;true;append;(Object[]);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Iterable);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;append;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;asEnumeration;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;collate;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;collate;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;copyInto;;;Argument[-1].Element;Argument[0].Element;value;manual", - ";FluentIterable;true;eval;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;filter;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ";FluentIterable;true;limit;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;loop;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";FluentIterable;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - ";FluentIterable;true;reverse;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;skip;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;toArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ";FluentIterable;true;toList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;unique;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;unmodifiable;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable[]);;Argument[-1].Element;ReturnValue.Element;value;manual", - ";FluentIterable;true;zip;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";Get;true;entrySet;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ";Get;true;entrySet;;;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - ";Get;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";Get;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";Get;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - ";Get;true;remove;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - ";IterableGet;true;mapIterator;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";IterableGet;true;mapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ";KeyValue;true;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";KeyValue;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - // Note that MapIterator implements Iterator, so it iterates over the keys of the map. - // In order for the models of Iterator to work we have to use Element instead of MapKey for key data. - ";MapIterator;true;getKey;;;Argument[-1].Element;ReturnValue;value;manual", - ";MapIterator;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";MapIterator;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";MapIterator;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ";MultiMap;true;get;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMap;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiMap;true;put;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - ";MultiMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiSet$Entry;true;getElement;;;Argument[-1].Element;ReturnValue;value;manual", - ";MultiSet;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ";MultiSet;true;uniqueSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";MultiSet;true;entrySet;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ";MultiValuedMap;true;asMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ";MultiValuedMap;true;asMap;;;Argument[-1].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ";MultiValuedMap;true;entries;;;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ";MultiValuedMap;true;entries;;;Argument[-1].MapValue.Element;ReturnValue.Element.MapValue;value;manual", - ";MultiValuedMap;true;get;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;keys;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;keySet;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;mapIterator;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;mapIterator;;;Argument[-1].MapValue.Element;ReturnValue.MapValue;value;manual", - ";MultiValuedMap;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;put;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;putAll;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";MultiValuedMap;true;putAll;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ";MultiValuedMap;true;remove;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiValuedMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ";OrderedIterator;true;previous;;;Argument[-1].Element;ReturnValue;value;manual", - ";OrderedMap;true;firstKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;lastKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;nextKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";OrderedMap;true;previousKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ";Put;true;put;;;Argument[-1].MapValue;ReturnValue;value;manual", - ";Put;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - ";Put;true;put;;;Argument[1];Argument[-1].MapValue;value;manual", - ";Put;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ";Put;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ";SortedBag;true;first;;;Argument[-1].Element;ReturnValue;value;manual", - ";SortedBag;true;last;;;Argument[-1].Element;ReturnValue;value;manual", - ";Trie;true;prefixMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ";Trie;true;prefixMap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -// Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`, -// and when more general callable flow is supported we should model the package -// `org.apache.commons.collections4.sequence`. -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.keyvalue`. - */ -private class ApacheKeyValueModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setKey;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractKeyValue;true;setValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".keyvalue;AbstractKeyValue;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultKeyValue;true;toMapEntry;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".keyvalue;DefaultKeyValue;true;toMapEntry;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object[]);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object[],boolean);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[3];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[0];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[1];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[2];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[3];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[4];Argument[-1].Element;value;manual", - ".keyvalue;MultiKey;true;getKeys;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".keyvalue;MultiKey;true;getKey;;;Argument[-1].Element;ReturnValue;value;manual", - ".keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[1];Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.bag`. - */ -private class ApacheBagModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag - ".bag;AbstractBagDecorator;true;AbstractBagDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;AbstractMapBag;true;AbstractMapBag;;;Argument[0].MapKey;Argument[-1].Element;value;manual", - ".bag;AbstractMapBag;true;getMap;;;Argument[-1].Element;ReturnValue.MapKey;value;manual", - ".bag;AbstractSortedBagDecorator;true;AbstractSortedBagDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionBag;true;CollectionBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionBag;true;collectionBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;CollectionSortedBag;true;CollectionSortedBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;CollectionSortedBag;true;collectionSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;HashBag;true;HashBag;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;PredicatedBag;true;predicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;PredicatedSortedBag;true;predicatedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;SynchronizedBag;true;synchronizedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;SynchronizedSortedBag;true;synchronizedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TransformedBag;true;transformedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TransformedSortedBag;true;transformedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;TreeBag;true;TreeBag;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".bag;UnmodifiableBag;true;unmodifiableBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".bag;UnmodifiableSortedBag;true;unmodifiableSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.bidimap`. - */ -private class ApacheBidiMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[1].MapKey;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[1].MapValue;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[2].MapKey;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;Argument[2].MapValue;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;TreeBidiMap;true;TreeBidiMap;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".bidimap;TreeBidiMap;true;TreeBidiMap;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - ".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for classes in the package `org.apache.commons.collections4.collection`. - */ -private class ApacheCollectionModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedCollection - ".collection;AbstractCollectionDecorator;true;AbstractCollectionDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;AbstractCollectionDecorator;true;decorated;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;AbstractCollectionDecorator;true;setCollection;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Argument[0].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Argument[1].Element.Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;addAll;;;Argument[2].Element;Argument[0].Element;value;manual", - ".collection;CompositeCollection$CollectionMutator;true;addAll;;;Argument[2].Element;Argument[1].Element.Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;CompositeCollection;(Collection[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Argument[1].Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;addComposited;(Collection[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".collection;CompositeCollection;true;toCollection;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;CompositeCollection;true;getCollections;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".collection;IndexedCollection;true;IndexedCollection;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;IndexedCollection;true;uniqueIndexedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;IndexedCollection;true;nonUniqueIndexedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;IndexedCollection;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".collection;IndexedCollection;true;values;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;add;;;Argument[0];Argument[-1].Element;value;manual", - ".collection;PredicatedCollection$Builder;true;addAll;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection$Builder;true;rejectedElements;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".collection;PredicatedCollection;true;predicatedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;SynchronizedCollection;true;synchronizedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;TransformedCollection;true;transformingCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;UnmodifiableBoundedCollection;true;unmodifiableBoundedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".collection;UnmodifiableCollection;true;unmodifiableCollection;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.iterators`. - */ -private class ApacheIteratorsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformIterator - ".iterators;AbstractIteratorDecorator;true;AbstractIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractListIteratorDecorator;true;AbstractListIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractListIteratorDecorator;true;getListIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;AbstractUntypedIteratorDecorator;true;AbstractUntypedIteratorDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;AbstractUntypedIteratorDecorator;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;ArrayIterator;true;ArrayIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;ArrayIterator;true;getArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".iterators;ArrayListIterator;true;ArrayListIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;BoundedIterator;true;BoundedIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Argument[2].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator[]);;Argument[1].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Collection);;Argument[1].Element.Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;addIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;setIterator;;;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;CollatingIterator;true;getIterators;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".iterators;EnumerationIterator;true;EnumerationIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;EnumerationIterator;true;getEnumeration;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;EnumerationIterator;true;setEnumeration;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterIterator;true;FilterIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterIterator;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;FilterIterator;true;setIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;FilterListIterator;(ListIterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;FilterListIterator;(ListIterator,Predicate);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;FilterListIterator;true;getListIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;FilterListIterator;true;setListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Iterator[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;IteratorChain;(Collection);;Argument[0].Element.Element;Argument[-1].Element;value;manual", - ".iterators;IteratorChain;true;addIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorEnumeration;true;IteratorEnumeration;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorEnumeration;true;getIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".iterators;IteratorEnumeration;true;setIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;IteratorIterable;true;IteratorIterable;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ListIteratorWrapper;true;ListIteratorWrapper;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;LoopingIterator;true;LoopingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;LoopingListIterator;true;LoopingListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ObjectArrayIterator;true;ObjectArrayIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;ObjectArrayIterator;true;getArray;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - ".iterators;ObjectArrayListIterator;true;ObjectArrayListIterator;;;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - ".iterators;PeekingIterator;true;PeekingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;PeekingIterator;true;peekingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;PeekingIterator;true;peek;;;Argument[-1].Element;ReturnValue;value;manual", - ".iterators;PeekingIterator;true;element;;;Argument[-1].Element;ReturnValue;value;manual", - ".iterators;PermutationIterator;true;PermutationIterator;;;Argument[0].Element;Argument[-1].Element.Element;value;manual", - ".iterators;PushbackIterator;true;PushbackIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;PushbackIterator;true;pushbackIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;PushbackIterator;true;pushback;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;ReverseListIterator;true;ReverseListIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;SingletonIterator;true;SingletonIterator;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;SingletonListIterator;true;SingletonListIterator;;;Argument[0];Argument[-1].Element;value;manual", - ".iterators;SkippingIterator;true;SkippingIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;UniqueFilterIterator;true;UniqueFilterIterator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;UnmodifiableIterator;true;unmodifiableIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableListIterator;true;umodifiableListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[1].Element;Argument[-1].Element;value;manual", - ".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Argument[2].Element;Argument[-1].Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.list`. - */ -private class ApacheListModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedList - ".list;AbstractLinkedList;true;AbstractLinkedList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;getFirst;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;getLast;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;addFirst;;;Argument[0];Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;addLast;;;Argument[0];Argument[-1].Element;value;manual", - ".list;AbstractLinkedList;true;removeFirst;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractLinkedList;true;removeLast;;;Argument[-1].Element;ReturnValue;value;manual", - ".list;AbstractListDecorator;true;AbstractListDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;AbstractSerializableListDecorator;true;AbstractSerializableListDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;CursorableLinkedList;true;CursorableLinkedList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;CursorableLinkedList;true;cursor;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".list;FixedSizeList;true;fixedSizeList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;GrowthList;true;growthList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;LazyList;true;lazyList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;NodeCachingLinkedList;true;NodeCachingLinkedList;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;PredicatedList;true;predicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;SetUniqueList;true;setUniqueList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;SetUniqueList;true;asSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".list;TransformedList;true;transformingList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".list;TreeList;true;TreeList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;UnmodifiableList;true;UnmodifiableList;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".list;UnmodifiableList;true;unmodifiableList;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.map`. - */ -private class ApacheMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap - ".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractMapDecorator;true;decorated;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".map;AbstractMapDecorator;true;decorated;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[]);;Argument[0].ArrayElement.MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[]);;Argument[0].ArrayElement.MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;Argument[0].ArrayElement.MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;Argument[0].ArrayElement.MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;addComposited;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;CompositeMap;true;addComposited;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".map;CompositeMap;true;removeComposited;;;Argument[0];ReturnValue;value;manual", - ".map;DefaultedMap;true;DefaultedMap;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - ".map;DefaultedMap;true;defaultedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;DefaultedMap;true;defaultedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;DefaultedMap;true;defaultedMap;(Map,Object);;Argument[1];ReturnValue.MapValue;value;manual", - ".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;Argument[0].Element.MapKey;Argument[-1].Element;value;manual", - ".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - ".map;FixedSizeMap;true;fixedSizeMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;FixedSizeMap;true;fixedSizeMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;Flat3Map;true;Flat3Map;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;Flat3Map;true;Flat3Map;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;HashedMap;true;HashedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;HashedMap;true;HashedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LazyMap;true;lazyMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;LazyMap;true;lazyMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;LazySortedMap;true;lazySortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;LazySortedMap;true;lazySortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;LinkedMap;true;LinkedMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LinkedMap;true;LinkedMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LinkedMap;true;get;(int);;Argument[-1].MapKey;ReturnValue;value;manual", - ".map;LinkedMap;true;getValue;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;LinkedMap;true;remove;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;LinkedMap;true;asList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;listOrderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;ListOrderedMap;true;listOrderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;ListOrderedMap;true;putAll;;;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;ListOrderedMap;true;putAll;;;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;keyList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;valueList;;;Argument[-1].MapValue;ReturnValue.Element;value;manual", - ".map;ListOrderedMap;true;get;(int);;Argument[-1].MapKey;ReturnValue;value;manual", - ".map;ListOrderedMap;true;getValue;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;ListOrderedMap;true;setValue;;;Argument[1];Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;put;;;Argument[1];Argument[-1].MapKey;value;manual", - ".map;ListOrderedMap;true;put;;;Argument[2];Argument[-1].MapValue;value;manual", - ".map;ListOrderedMap;true;remove;(int);;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;ListOrderedMap;true;asList;;;Argument[-1].MapKey;ReturnValue.Element;value;manual", - ".map;LRUMap;true;LRUMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LRUMap;true;LRUMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LRUMap;true;LRUMap;(Map,boolean);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;LRUMap;true;LRUMap;(Map,boolean);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;LRUMap;true;get;(Object,boolean);;Argument[0].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;put;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[0..1];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[0..2];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[0..3];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[0..4];Argument[-1].MapKey.Element;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[3];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[4];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[5];Argument[-1].MapValue;value;manual", - ".map;MultiKeyMap;true;removeMultiKey;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".map;MultiValueMap;true;multiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;MultiValueMap;true;multiValueMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ".map;MultiValueMap;true;getCollection;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Map);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;values;;;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;putAll;(Object,Collection);;Argument[0];Argument[-1].MapKey;value;manual", - ".map;MultiValueMap;true;putAll;(Object,Collection);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - ".map;MultiValueMap;true;iterator;(Object);;Argument[-1].MapValue.Element;ReturnValue.Element;value;manual", - ".map;MultiValueMap;true;iterator;();;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - ".map;MultiValueMap;true;iterator;();;Argument[-1].MapValue.Element;ReturnValue.Element.MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;Argument[1].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;Argument[1].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;Argument[2].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;Argument[2].MapValue;Argument[-1].MapValue;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;PredicatedMap;true;predicatedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;PredicatedMap;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;PredicatedSortedMap;true;predicatedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;PredicatedSortedMap;true;predicatedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(KeyValue);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(KeyValue);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;SingletonMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".map;SingletonMap;true;SingletonMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".map;SingletonMap;true;setValue;;;Argument[0];Argument[-1].MapValue;value;manual", - ".map;TransformedMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;TransformedMap;true;transformingMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;TransformedSortedMap;true;transformingSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;TransformedSortedMap;true;transformingSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;Argument[0].Element.MapKey;ReturnValue.Element.MapKey;value;manual", - ".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;Argument[0].Element.MapValue;ReturnValue.Element.MapValue;value;manual", - ".map;UnmodifiableMap;true;unmodifiableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableMap;true;unmodifiableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.multimap`. - */ -private class ApacheMultiMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedMultiValuedMap - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - ".multimap;TransformedMultiValuedMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".multimap;TransformedMultiValuedMap;true;transformingMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.multiset`. - */ -private class ApacheMultiSetModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".multiset;HashMultiSet;true;HashMultiSet;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".multiset;PredicatedMultiSet;true;predicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".multiset;SynchronizedMultiSet;true;synchronizedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".multiset;UnmodifiableMultiSet;true;unmodifiableMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.properties`. - */ -private class ApachePropertiesModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ".properties;AbstractPropertiesFactory;true;load;(ClassLoader,String);;Argument[1];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(File);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(InputStream);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(Path);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(Reader);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(String);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(URI);;Argument[0];ReturnValue;taint;manual", - ".properties;AbstractPropertiesFactory;true;load;(URL);;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.queue`. - */ -private class ApacheQueueModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedQueue - ".queue;CircularFifoQueue;true;CircularFifoQueue;(Collection);;Argument[0].Element;Argument[-1].Element;value;manual", - ".queue;CircularFifoQueue;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".queue;PredicatedQueue;true;predicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;SynchronizedQueue;true;synchronizedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;TransformedQueue;true;transformingQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".queue;UnmodifiableQueue;true;unmodifiableQueue;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.set`. - */ -private class ApacheSetModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedNavigableSet - ".set;AbstractNavigableSetDecorator;true;AbstractNavigableSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;AbstractSetDecorator;true;AbstractSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;AbstractSortedSetDecorator;true;AbstractSortedSetDecorator;;;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet$SetMutator;true;add;;;Argument[2];Argument[0].Element;value;manual", - ".set;CompositeSet$SetMutator;true;add;;;Argument[2];Argument[1].Element.Element;value;manual", - ".set;CompositeSet$SetMutator;true;addAll;;;Argument[2].Element;Argument[0].Element;value;manual", - ".set;CompositeSet$SetMutator;true;addAll;;;Argument[2].Element;Argument[1].Element.Element;value;manual", - ".set;CompositeSet;true;CompositeSet;(Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;CompositeSet;(Set[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set,Set);;Argument[0].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set,Set);;Argument[1].Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;addComposited;(Set[]);;Argument[0].ArrayElement.Element;Argument[-1].Element;value;manual", - ".set;CompositeSet;true;toSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".set;CompositeSet;true;getSets;;;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - ".set;ListOrderedSet;true;listOrderedSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;listOrderedSet;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;asList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ".set;ListOrderedSet;true;get;;;Argument[-1].Element;ReturnValue;value;manual", - ".set;ListOrderedSet;true;add;;;Argument[1];Argument[-1].Element;value;manual", - ".set;ListOrderedSet;true;addAll;;;Argument[1].Element;Argument[-1].Element;value;manual", - ".set;MapBackedSet;true;mapBackedSet;;;Argument[0].MapKey;ReturnValue.Element;value;manual", - ".set;PredicatedNavigableSet;true;predicatedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;PredicatedSet;true;predicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;PredicatedSortedSet;true;predicatedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedNavigableSet;true;transformingNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedSet;true;transformingSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;TransformedSortedSet;true;transformingSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableNavigableSet;true;unmodifiableNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableSet;true;unmodifiableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ".set;UnmodifiableSortedSet;true;unmodifiableSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.splitmap`. - */ -private class ApacheSplitMapModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedSplitMap - ".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".splitmap;TransformedSplitMap;true;transformingMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".splitmap;TransformedSplitMap;true;transformingMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the package `org.apache.commons.collections4.trie`. - */ -private class ApacheTrieModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for TransformedSplitMap - ".trie;PatriciaTrie;true;PatriciaTrie;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - ".trie;PatriciaTrie;true;PatriciaTrie;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - ".trie;AbstractPatriciaTrie;true;select;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - ".trie;AbstractPatriciaTrie;true;select;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - ".trie;AbstractPatriciaTrie;true;selectKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - ".trie;AbstractPatriciaTrie;true;selectValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - ".trie;UnmodifiableTrie;true;unmodifiableTrie;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ".trie;UnmodifiableTrie;true;unmodifiableTrie;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MapUtils`. - */ -private class ApacheMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have more models for populateMap - ";MapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";MapUtils;true;fixedSizeMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;fixedSizeMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;fixedSizeSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;fixedSizeSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;getMap;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getMap;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;getObject;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getObject;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;getString;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MapUtils;true;getString;;;Argument[2];ReturnValue;value;manual", - ";MapUtils;true;invertMap;;;Argument[0].MapKey;ReturnValue.MapValue;value;manual", - ";MapUtils;true;invertMap;;;Argument[0].MapValue;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;iterableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;iterableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;lazyMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;lazyMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;lazySortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;lazySortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;multiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;multiValueMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;orderedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;orderedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;populateMap;(Map,Iterable,Transformer);;Argument[1].Element;Argument[0].MapValue;value;manual", - ";MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Argument[1].Element;Argument[0].MapValue.Element;value;manual", - ";MapUtils;true;predicatedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;predicatedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;predicatedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.ArrayElement;ReturnValue.MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapKey;Argument[0].MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapValue;Argument[0].MapValue;value;manual", - ";MapUtils;true;putAll;;;Argument[1].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;safeAddToMap;;;Argument[1];Argument[0].MapKey;value;manual", - ";MapUtils;true;safeAddToMap;;;Argument[2];Argument[0].MapValue;value;manual", - ";MapUtils;true;synchronizedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;synchronizedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;synchronizedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;synchronizedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;toMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;toMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;transformedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;transformedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;transformedSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;transformedSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;unmodifiableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;unmodifiableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";MapUtils;true;unmodifiableSortedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MapUtils;true;unmodifiableSortedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.CollectionUtils`. - */ -private class ApacheCollectionUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have a model for collect, forAllButLastDo, forAllDo, transform - ";CollectionUtils;true;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Enumeration);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addAll;(Collection,Iterator);;Argument[1].Element;Argument[0].Element;value;manual", - ";CollectionUtils;true;addIgnoreNull;;;Argument[1];Argument[0].Element;value;manual", - ";CollectionUtils;true;collate;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;collate;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;disjunction;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;disjunction;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";CollectionUtils;true;extractSingleton;;;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Iterator,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Iterable,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Map,int);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;get;(Map,int);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].ArrayElement;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].Element;ReturnValue;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;get;(Object,int);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";CollectionUtils;true;getCardinalityMap;;;Argument[0].Element;ReturnValue.MapKey;value;manual", - ";CollectionUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;permutations;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";CollectionUtils;true;predicatedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;removeAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;retainAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[0].Element;Argument[3].Element;value;manual", - ";CollectionUtils;true;select;(Iterable,Predicate,Collection,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate,Collection);;Argument[0].Element;Argument[2].Element;value;manual", - ";CollectionUtils;true;selectRejected;(Iterable,Predicate,Collection);;Argument[2];ReturnValue;value;manual", - ";CollectionUtils;true;subtract;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;synchronizedCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - // Note that `CollectionUtils.transformingCollection` does not transform existing list elements - ";CollectionUtils;true;transformingCollection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";CollectionUtils;true;unmodifiableCollection;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.ListUtils`. - */ -private class ApacheListUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";ListUtils;true;defaultIfNull;;;Argument[0];ReturnValue;value;manual", - ";ListUtils;true;defaultIfNull;;;Argument[1];ReturnValue;value;manual", - ";ListUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";ListUtils;true;fixedSizeList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - // Note that `ListUtils.lazyList` does not transform existing list elements - ";ListUtils;true;lazyList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;manual", - ";ListUtils;true;longestCommonSubsequence;(CharSequence,CharSequence);;Argument[1];ReturnValue;taint;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List);;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List);;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List,Equator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;longestCommonSubsequence;(List,List,Equator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;partition;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";ListUtils;true;predicatedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;removeAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;retainAll;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;select;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;selectRejected;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;subtract;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;sum;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;sum;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;synchronizedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - // Note that `ListUtils.transformedList` does not transform existing list elements - ";ListUtils;true;transformedList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";ListUtils;true;unmodifiableList;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.IteratorUtils`. - */ -private class ApacheIteratorUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - // Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterator - ";IteratorUtils;true;arrayIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;arrayListIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asEnumeration;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;asMultipleUseIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;boundedIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Collection);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;chainedIterator;(Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Collection);;Argument[1].Element.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator[]);;Argument[1].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;collatedIterator;(Comparator,Iterator,Iterator);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;filteredIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;filteredListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;first;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;forEachButLast;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;getIterator;;;Argument[0].MapValue;ReturnValue.Element;value;manual", - ";IteratorUtils;true;loopingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;loopingListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;peekingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;pushbackIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;singletonIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;singletonListIterator;;;Argument[0];ReturnValue.Element;value;manual", - ";IteratorUtils;true;skippingIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - ";IteratorUtils;true;toList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;toString;;;Argument[2];ReturnValue;taint;manual", - ";IteratorUtils;true;toString;;;Argument[3];ReturnValue;taint;manual", - ";IteratorUtils;true;toString;;;Argument[4];ReturnValue;taint;manual", - ";IteratorUtils;true;unmodifiableIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableListIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableMapIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;unmodifiableMapIterator;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IteratorUtils;true;zippingIterator;(Iterator,Iterator,Iterator);;Argument[2].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.IterableUtils`. - */ -private class ApacheIterableUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - // Note that when lambdas are supported we should have a model for forEach, forEachButLast, transformedIterable - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";IterableUtils;true;boundedIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;chainedIterable;(Iterable,Iterable,Iterable,Iterable);;Argument[3].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Comparator,Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Comparator,Iterable,Iterable);;Argument[2].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Iterable,Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;collatedIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";IterableUtils;true;filteredIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;find;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;first;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;forEachButLast;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";IterableUtils;true;loopingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;partition;;;Argument[0].Element;ReturnValue.Element.Element;value;manual", - ";IterableUtils;true;reversedIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;skippingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;toList;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;toString;;;Argument[2];ReturnValue;taint;manual", - ";IterableUtils;true;toString;;;Argument[3];ReturnValue;taint;manual", - ";IterableUtils;true;toString;;;Argument[4];ReturnValue;taint;manual", - ";IterableUtils;true;uniqueIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;unmodifiableIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;(Iterable,Iterable[]);;Argument[1].ArrayElement.Element;ReturnValue.Element;value;manual", - ";IterableUtils;true;zippingIterable;(Iterable,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.EnumerationUtils`. - */ -private class ApacheEnumerationUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";EnumerationUtils;true;get;;;Argument[0].Element;ReturnValue;value;manual", - ";EnumerationUtils;true;toList;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - ";EnumerationUtils;true;toList;(StringTokenizer);;Argument[0];ReturnValue.Element;taint;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MultiMapUtils`. - */ -private class ApacheMultiMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";MultiMapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";MultiMapUtils;true;getCollection;;;Argument[0].MapValue;ReturnValue;value;manual", - ";MultiMapUtils;true;getValuesAsBag;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;getValuesAsList;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;getValuesAsSet;;;Argument[0].MapValue.Element;ReturnValue.Element;value;manual", - ";MultiMapUtils;true;transformedMultiValuedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MultiMapUtils;true;transformedMultiValuedMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - ";MultiMapUtils;true;unmodifiableMultiValuedMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";MultiMapUtils;true;unmodifiableMultiValuedMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.MultiSetUtils`. - */ -private class ApacheMultiSetUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";MultiSetUtils;true;predicatedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";MultiSetUtils;true;synchronizedMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";MultiSetUtils;true;unmodifiableMultiSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.QueueUtils`. - */ -private class ApacheQueueUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";QueueUtils;true;predicatedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;synchronizedQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;transformingQueue;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";QueueUtils;true;unmodifiableQueue;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the classes `org.apache.commons.collections4.SetUtils` - * and `org.apache.commons.collections4.SetUtils$SetView`. - */ -private class ApacheSetUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";SetUtils$SetView;true;copyInto;;;Argument[-1].Element;Argument[0].Element;value;manual", - ";SetUtils$SetView;true;createIterator;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";SetUtils$SetView;true;toSet;;;Argument[-1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;difference;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;disjunction;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;disjunction;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value;manual", - ";SetUtils;true;hashSet;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";SetUtils;true;intersection;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;intersection;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;orderedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;predicatedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;synchronizedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;synchronizedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;transformedSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;union;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;union;;;Argument[1].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableNavigableSet;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSet;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSet;(Set);;Argument[0].Element;ReturnValue.Element;value;manual", - ";SetUtils;true;unmodifiableSortedSet;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.SplitMapUtils`. - */ -private class ApacheSplitMapUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";SplitMapUtils;true;readableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";SplitMapUtils;true;readableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - ";SplitMapUtils;true;writableMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";SplitMapUtils;true;writableMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.TrieUtils`. - */ -private class ApacheTrieUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";TrieUtils;true;unmodifiableTrie;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - ";TrieUtils;true;unmodifiableTrie;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} - -/** - * Value-propagating models for the class `org.apache.commons.collections4.BagUtils`. - */ -private class ApacheBagUtilsModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["org.apache.commons.collections4", "org.apache.commons.collections"] + - [ - ";BagUtils;true;collectionBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;predicatedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;predicatedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;synchronizedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;synchronizedSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;transformingBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;transformingSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;unmodifiableBag;;;Argument[0].Element;ReturnValue.Element;value;manual", - ";BagUtils;true;unmodifiableSortedBag;;;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll index 978154d3274..5f44f878eb2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Exec.qll @@ -1,4 +1,5 @@ -/* Definitions related to the Apache Commons Exec library. */ +/** Definitions related to the Apache Commons Exec library. */ + import semmle.code.java.Type import semmle.code.java.security.ExternalProcess diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll b/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll deleted file mode 100644 index 997bffb9110..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/IO.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** Custom definitions related to the Apache Commons IO library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsIOCustomSummaryCsv extends SummaryModelCsv { - /** - * Models that are not yet auto generated or where the generated summaries will - * be ignored. - * Note that if a callable has any handwritten summary, all generated summaries - * will be ignored for that callable. - */ - override predicate row(string row) { - row = - [ - "org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[0].Element;Argument[2];taint;manual", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[1];Argument[2];taint;manual", - "org.apache.commons.io;IOUtils;true;toByteArray;(Reader);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.io;IOUtils;true;toByteArray;(Reader,String);;Argument[0];ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll deleted file mode 100644 index 931764d56d8..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/IOGenerated.qll +++ /dev/null @@ -1,680 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the IOGenerated framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class IOGeneratedSinksCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.file;PathFilter;true;accept;(Path,BasicFileAttributes);;Argument[0];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[0];open-url;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[0];open-url;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;newOutputStream;(Path,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.file;PathUtils;false;writeString;(Path,CharSequence,Charset,OpenOption[]);;Argument[0];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filter;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filterList;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;filterSet;(IOFileFilter,File[]);;Argument[1];create-file;generated", - "org.apache.commons.io.input;Tailer$Tailable;true;getRandomAccess;(String);;Argument[-1];create-file;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;writeTo;(OutputStream);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,CharsetEncoder);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,CharsetEncoder,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(File,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,CharsetEncoder);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,CharsetEncoder,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;FileWriterWithEncoding;true;FileWriterWithEncoding;(String,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean,String);;Argument[0];create-file;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File);;Argument[0];create-file;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,FileFilter,boolean,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyDirectoryToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFile;(File,File,boolean,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFileToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyFileToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyInputStreamToFile;(InputStream,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToDirectory;(Iterable,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyToFile;(InputStream,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File);;Argument[0];open-url;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File,int,int);;Argument[0];open-url;generated", - "org.apache.commons.io;FileUtils;true;copyURLToFile;(URL,File,int,int);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveDirectory;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveDirectoryToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFile;(File,File);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFile;(File,File,CopyOption[]);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveFileToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;moveToDirectory;(File,File,boolean);;Argument[1];create-file;generated", - "org.apache.commons.io;FileUtils;true;newOutputStream;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;openOutputStream;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;openOutputStream;(File,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;touch;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;write;(File,CharSequence,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[]);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],int,int);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeByteArrayToFile;(File,byte[],int,int,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,Collection,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeLines;(File,String,Collection,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,Charset);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,Charset,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,String);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;FileUtils;true;writeStringToFile;(File,String,boolean);;Argument[0];create-file;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,File);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,File);;Argument[1];create-file;generated", - "org.apache.commons.io;IOUtils;true;copy;(URL,OutputStream);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(URI);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI,Charset);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URI,String);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL,Charset);;Argument[0];open-url;generated", - "org.apache.commons.io;IOUtils;true;toString;(URL,String);;Argument[0];open-url;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(File);;Argument[0];create-file;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(Path);;Argument[0];create-file;generated", - "org.apache.commons.io;RandomAccessFileMode;false;create;(String);;Argument[0];create-file;generated" - ] - } -} - -private class IOGeneratedSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.charset;CharsetDecoders;true;toCharsetDecoder;(CharsetDecoder);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.charset;CharsetEncoders;true;toCharsetEncoder;(CharsetEncoder);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;CompositeFileComparator;(Comparator[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;CompositeFileComparator;(Iterable);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.comparator;CompositeFileComparator;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(String);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(URI);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file.spi;FileSystemProviders;true;getFileSystemProvider;(URL);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;AccumulatorPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;getDirList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;getFileList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withBigIntegerCounters;(PathFilter,PathFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withBigIntegerCounters;(PathFilter,PathFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withLongCounters;(PathFilter,PathFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;true;withLongCounters;(PathFilter,PathFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CleaningPathVisitor;true;CleaningPathVisitor;(PathCounters,String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[2].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,Path,Path,CopyOption[]);;Argument[3].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[3].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[4].Element;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;CopyDirectoryVisitor;(PathCounters,PathFilter,PathFilter,Path,Path,CopyOption[]);;Argument[5].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getCopyOptions;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getSourceDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CopyDirectoryVisitor;true;getTargetDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getByteCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getDirectoryCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;Counters$PathCounters;true;getFileCounter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;CountingPathVisitor;(PathCounters,PathFilter,PathFilter);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.file;CountingPathVisitor;true;getPathCounters;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,DeleteOption[],String[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,LinkOption[],DeleteOption[],String[]);;Argument[3].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,String[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DeletingPathVisitor;true;DeletingPathVisitor;(PathCounters,String[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.file;DirectoryStreamFilter;true;DirectoryStreamFilter;(PathFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.file;DirectoryStreamFilter;true;getPathFilter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[1].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[1].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;setReadOnly;(Path,boolean,LinkOption[]);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,Path);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,Path,Set,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,String,String[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;visitFileTree;(FileVisitor,URI);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.file;PathUtils;false;writeString;(Path,CharSequence,Charset,OpenOption[]);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;AgeFileFilter;(Instant);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;AgeFileFilter;(Instant,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AgeFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;AndFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;addFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;AndFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;addFileFilter;(IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;getFileFilters;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;true;setFileFilters;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;DelegateFileFilter;(FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;DelegateFileFilter;(FilenameFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;DelegateFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileEqualsFileFilter;true;FileEqualsFileFilter;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;and;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;andFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;andFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;asFileFilter;(FileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;asFileFilter;(FilenameFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(String,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(byte[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;magicNumberFileFilter;(byte[],long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeCVSAware;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeDirectoryOnly;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeFileOnly;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;makeSVNAware;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;nameFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;nameFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;notFileFilter;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;or;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;orFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;orFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;prefixFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;prefixFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;suffixFileFilter;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;suffixFileFilter;(String,IOCase);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;FileFilterUtils;true;toList;(IOFileFilter[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;and;(IOFileFilter);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;and;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;negate;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;or;(IOFileFilter);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;IOFileFilter;true;or;(IOFileFilter);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(String,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;MagicNumberFileFilter;(byte[],long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;MagicNumberFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;NameFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NameFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;NotFileFilter;true;NotFileFilter;(IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;NotFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter,IOFileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter,IOFileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;OrFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;addFileFilter;(IOFileFilter[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;OrFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;PathEqualsFileFilter;true;PathEqualsFileFilter;(Path);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PathVisitorFileFilter;true;PathVisitorFileFilter;(PathVisitor);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;PrefixFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;PrefixFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern,Function);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;RegexFileFilter;(Pattern,Function);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;RegexFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;SuffixFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;SuffixFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(List,IOCase);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;WildcardFileFilter;(String[],IOCase);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFileFilter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.filefilter;WildcardFilter;true;WildcardFilter;(String[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;CircularBufferInputStream;true;CircularBufferInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;CircularBufferInputStream;true;CircularBufferInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;true;PeekableInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;true;PeekableInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;BOMInputStream;(InputStream,ByteOrderMark[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;BOMInputStream;(InputStream,boolean,ByteOrderMark[]);;Argument[2].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;getBOM;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;BOMInputStream;true;getBOMCharsetName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;BoundedInputStream;true;BoundedInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BoundedInputStream;true;BoundedInputStream;(InputStream,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BoundedReader;true;BoundedReader;(Reader,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BrokenInputStream;true;BrokenInputStream;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;BrokenReader;true;BrokenReader;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;CharSequenceReader;(CharSequence,int,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;CharSequenceReader;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;CharacterFilterReader;true;CharacterFilterReader;(Reader,IntPredicate);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;CircularInputStream;true;CircularInputStream;(byte[],long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ClassLoaderObjectInputStream;true;ClassLoaderObjectInputStream;(ClassLoader,InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ClassLoaderObjectInputStream;true;ClassLoaderObjectInputStream;(ClassLoader,InputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;CloseShieldInputStream;true;wrap;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;InfiniteCircularInputStream;true;InfiniteCircularInputStream;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream$MessageDigestMaintainingObserver;true;MessageDigestMaintainingObserver;(MessageDigest);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;true;MessageDigestCalculatingInputStream;(InputStream,MessageDigest);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;true;getMessageDigest;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;ObservableInputStream;(InputStream,Observer[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;add;(Observer);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ObservableInputStream;true;getObservers;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;RandomAccessFileInputStream;(RandomAccessFile);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;RandomAccessFileInputStream;(RandomAccessFile,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;true;getRandomAccessFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int,ExecutorService);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReadAheadInputStream;true;ReadAheadInputStream;(InputStream,int,ExecutorService);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,Charset);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,Charset,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,CharsetEncoder,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReaderInputStream;true;ReaderInputStream;(Reader,String,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;readLine;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;readLines;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;ReversedLinesFileReader;true;toString;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;SequenceReader;true;SequenceReader;(Iterable);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.input;SequenceReader;true;SequenceReader;(Reader[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(File,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(File,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Path,TailerListener);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Path,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Tailable,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;Builder;(Tailable,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;build;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withBufferSize;(int);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withCharset;(Charset);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withDelayDuration;(Duration);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withDelayDuration;(Duration);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withReOpen;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withStartThread;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer$Builder;true;withTailFromEnd;(boolean);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,boolean,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;Tailer;(File,TailerListener,long,boolean,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,Charset,TailerListener,long,boolean,boolean,int);;Argument[2];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,boolean,int);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;create;(File,TailerListener,long,boolean,int);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getDelayDuration;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;Tailer;true;getTailable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TeeInputStream;true;TeeInputStream;(InputStream,OutputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeInputStream;true;TeeInputStream;(InputStream,OutputStream,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeReader;true;TeeReader;(Reader,Writer);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TeeReader;true;TeeReader;(Reader,Writer,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;getCloseInstant;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;getOpenInstant;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;TimestampedObserver;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;UncheckedBufferedReader;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;UncheckedBufferedReader;(Reader,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UncheckedBufferedReader;true;on;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;UncheckedFilterInputStream;true;on;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.input;UnixLineEndingInputStream;true;UnixLineEndingInputStream;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[],int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;UnsynchronizedByteArrayInputStream;true;UnsynchronizedByteArrayInputStream;(byte[],int,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;WindowsLineEndingInputStream;true;WindowsLineEndingInputStream;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,String,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(InputStream,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;XmlStreamReader;(URLConnection,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;getDefaultEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReader;true;getEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[4];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;XmlStreamReaderException;(String,String,String,String,String,String);;Argument[5];Argument[-1];taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getBomEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getContentTypeEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getContentTypeMime;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getXmlEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.input;XmlStreamReaderException;true;getXmlGuessEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;FileAlterationMonitor;(long,Collection);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;FileAlterationMonitor;(long,FileAlterationObserver[]);;Argument[1].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;addObserver;(FileAlterationObserver);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;getObservers;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;false;setThreadFactory;(ThreadFactory);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(File,FileFilter,IOCase);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter,IOCase);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;FileAlterationObserver;(String,FileFilter,IOCase);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;addListener;(FileAlterationListener);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getDirectory;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getFileFilter;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;getListeners;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileAlterationObserver;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(FileEntry,File);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;FileEntry;(FileEntry,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getChildren;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getLastModifiedFileTime;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;getParent;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;newChildInstance;(File);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;newChildInstance;(File);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setChildren;(FileEntry[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setLastModified;(FileTime);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.monitor;FileEntry;true;setName;(String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toByteArray;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;(Charset);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;toString;(String);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;write;(InputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;write;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;true;writeTo;(OutputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;AppendableOutputStream;true;AppendableOutputStream;(Appendable);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AppendableOutputStream;true;getAppendable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;AppendableWriter;true;AppendableWriter;(Appendable);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;AppendableWriter;true;getAppendable;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;BrokenOutputStream;true;BrokenOutputStream;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;BrokenWriter;true;BrokenWriter;(Supplier);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;ChunkedOutputStream;true;ChunkedOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;ChunkedOutputStream;true;ChunkedOutputStream;(OutputStream,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;CloseShieldOutputStream;true;CloseShieldOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;CloseShieldOutputStream;true;wrap;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;CountingOutputStream;true;CountingOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,String,String,File);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;DeferredFileOutputStream;(int,int,String,String,File);;Argument[4];Argument[-1];taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;getData;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;DeferredFileOutputStream;true;writeTo;(OutputStream);;Argument[-1];Argument[0];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,Charset,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,String,boolean,String);;Argument[3];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(File,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;LockableFileWriter;true;LockableFileWriter;(String,boolean,String);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyCollectionWriter;true;ProxyCollectionWriter;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyCollectionWriter;true;ProxyCollectionWriter;(Writer[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.output;ProxyOutputStream;true;ProxyOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;StringBuilderWriter;(StringBuilder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;getBuilder;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;StringBuilderWriter;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;TaggedOutputStream;true;TaggedOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeOutputStream;true;TeeOutputStream;(OutputStream,OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeOutputStream;true;TeeOutputStream;(OutputStream,OutputStream);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeWriter;true;TeeWriter;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io.output;TeeWriter;true;TeeWriter;(Writer[]);;Argument[0].ArrayElement;Argument[-1];taint;generated", - "org.apache.commons.io.output;ThresholdingOutputStream;true;ThresholdingOutputStream;(int,IOConsumer,IOFunction);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;ThresholdingOutputStream;true;ThresholdingOutputStream;(int,IOConsumer,IOFunction);;Argument[2];Argument[-1];taint;generated", - "org.apache.commons.io.output;UncheckedAppendable;true;on;(Appendable);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;UncheckedFilterOutputStream;true;UncheckedFilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;UncheckedFilterOutputStream;true;on;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,Charset);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,Charset,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,CharsetDecoder,int,boolean);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;WriterOutputStream;true;WriterOutputStream;(Writer,String,int,boolean);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(File,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream,String);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;XmlStreamWriter;(OutputStream,String);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;getDefaultEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.output;XmlStreamWriter;true;getEncoding;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;ValidatingObjectInputStream;(InputStream);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(ClassNameMatcher);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(ClassNameMatcher);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(Class[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(Pattern);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;accept;(String[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(ClassNameMatcher);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(ClassNameMatcher);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(Class[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(Pattern);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io.serialization;ValidatingObjectInputStream;true;reject;(String[]);;Argument[-1];ReturnValue;value;generated", - "org.apache.commons.io;ByteOrderMark;true;ByteOrderMark;(String,int[]);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;ByteOrderMark;true;getCharsetName;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;ByteOrderMark;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(InputStream,Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(String,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;CopyUtils;true;copy;(byte[],Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;CancelException;(File,int);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;CancelException;(String,File,int);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io;DirectoryWalker$CancelException;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileCleaningTracker;true;getDeleteFailures;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileDeleteStrategy;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;FileSystem;false;toLegalFileName;(String,char);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;checksum;(File,Checksum);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;convertFileCollectionToFileArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;delete;(File);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(File,String[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(File,String[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;getFile;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FileUtils;true;toURLs;(File[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;concat;(String,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;concat;(String,String);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getBaseName;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getExtension;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getFullPath;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getFullPathNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getName;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPath;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPathNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;getPrefix;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalize;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalize;(String,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;normalizeNoEndSeparator;(String,boolean);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;FilenameUtils;true;removeExtension;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(List);;Argument[0].Element;Argument[-1];taint;generated", - "org.apache.commons.io;IOExceptionList;true;IOExceptionList;(String,List);;Argument[1].Element;Argument[-1];taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCause;(int);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCauseList;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOExceptionList;true;getCauseList;(Class);;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(OutputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(OutputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Writer);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;buffer;(Writer,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,OutputStream,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer,Charset);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(InputStream,Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Appendable,CharBuffer);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copy;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,byte[]);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[0];Argument[4];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[4];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(InputStream,OutputStream,long,long,byte[]);;Argument[4];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[0];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[2];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,char[]);;Argument[2];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[0];Argument[4];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[4];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;copyLarge;(Reader,Writer,long,long,char[]);;Argument[4];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;lineIterator;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(InputStream,byte[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;read;(Reader,char[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,byte[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[]);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[]);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;readFully;(Reader,char[],int,int);;Argument[1];Argument[0];taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;readLines;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,long);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toByteArray;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toCharArray;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toInputStream;(String,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(InputStream,String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(Reader);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(byte[]);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;toString;(byte[],String);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;IOUtils;true;write;(CharSequence,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(String,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(StringBuffer,Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer,Charset);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(byte[],Writer,String);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;write;(char[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeChunked;(char[],Writer);;Argument[0];Argument[1];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,Charset);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,String);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[1];Argument[2];taint;generated", - "org.apache.commons.io;IOUtils;true;writer;(Appendable);;Argument[0];ReturnValue;taint;generated", - "org.apache.commons.io;LineIterator;true;LineIterator;(Reader);;Argument[0];Argument[-1];taint;generated", - "org.apache.commons.io;LineIterator;true;nextLine;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;TaggedIOException;true;TaggedIOException;(IOException,Serializable);;Argument[1];Argument[-1];taint;generated", - "org.apache.commons.io;TaggedIOException;true;getTag;();;Argument[-1];ReturnValue;taint;generated", - "org.apache.commons.io;UncheckedIO;true;apply;(IOFunction,Object);;Argument[1];ReturnValue;taint;generated", - "org.apache.commons.io;UncheckedIO;true;apply;(IOTriFunction,Object,Object,Object);;Argument[1];ReturnValue;taint;generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll index 84db672e935..9ea2400b871 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll @@ -1,10 +1,7 @@ /** Definitions related to the Apache Commons Lang library. */ import java -import Lang2Generated -import Lang3Generated private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow /** * The class `org.apache.commons.lang.RandomStringUtils` or `org.apache.commons.lang3.RandomStringUtils`. diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll deleted file mode 100644 index 3d9c8116c59..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang2Generated.qll +++ /dev/null @@ -1,284 +0,0 @@ -/** Definitions related to the Apache Commons Lang 2 library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsLangModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;append;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendln;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replace;(org.apache.commons.text.StrMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StrBuilder;false;StrBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.CharSequence,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.CharSequence);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuffer,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(java.lang.StringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;replaceIn;(org.apache.commons.text.TextStringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StringTokenizer;false;StringTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StringTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;StrTokenizer;false;StrTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;StrTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;append;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendln;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replace;(org.apache.commons.text.matcher.StringMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;TextStringBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;TextStringBuilder;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;TextStringBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text;TextStringBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.text;WordUtils;false;abbreviate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;abbreviate;;;Argument[3];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalizeFully;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;capitalizeFully;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;initials;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;initials;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;uncapitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;uncapitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.text.lookup;StringLookup;true;lookup;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;Argument[0].MapValue;ReturnValue;taint;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll deleted file mode 100644 index 532bb20619e..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/Lang3Generated.qll +++ /dev/null @@ -1,436 +0,0 @@ -/** Definitions related to the Apache Commons Lang 3 library. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class ApacheCommonsLang3Model extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[2];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(boolean[],boolean);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(byte[],byte);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(char[],char);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(double[],double);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(float[],float);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(int[],int);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(java.lang.Object[],java.lang.Object);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(long[],long);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;add;(short[],short);;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addAll;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;clone;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;get;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;get;(java.lang.Object[],int,java.lang.Object);;Argument[2];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;insert;;;Argument[1..2].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.Object[],java.lang.Class);;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.String[]);;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;remove;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAll;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAllOccurences;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeAllOccurrences;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeElement;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;removeElements;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;subarray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.ArrayElement;ReturnValue.MapKey;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.ArrayElement;ReturnValue.MapValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.MapKey;ReturnValue.MapKey;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0].ArrayElement.MapValue;ReturnValue.MapValue;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toObject;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;clone;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;cloneIfPossible;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST_BYTE;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST_SHORT;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;CONST;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;defaultIfNull;;;Argument[0..1];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;firstNonNull;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;getIfNull;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;max;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;median;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;min;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;mode;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;requireNonEmpty;;;Argument[0];ReturnValue;value;manual", - "org.apache.commons.lang3;ObjectUtils;false;toString;(Object,String);;Argument[1];ReturnValue;value;manual", - "org.apache.commons.lang3;RegExUtils;false;removeAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;removeFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;removePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceAll;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replacePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;RegExUtils;false;replacePattern;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringEscapeUtils;false;escapeJson;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;(java.lang.String,java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviate;(java.lang.String,java.lang.String,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviateMiddle;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;abbreviateMiddle;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissing;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissing;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissingIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;appendIfMissingIgnoreCase;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;capitalize;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;center;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;center;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chomp;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chomp;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;chop;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultIfBlank;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultIfEmpty;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;defaultString;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;deleteWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;difference;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;Argument[0].ArrayElement;ReturnValue;value;manual", - "org.apache.commons.lang3;StringUtils;false;getBytes;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getDigits;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getIfBlank;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;getIfEmpty;;;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(char[],char,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(char[],char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[0].Element;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;left;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;leftPad;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;leftPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;lowerCase;(java.lang.String,java.util.Locale);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;lowerCase;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;mid;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;normalizeSpace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;overlay;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;overlay;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissing;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissing;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissingIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;prependIfMissingIgnoreCase;;;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;remove;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeEnd;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeEndIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeStart;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;removeStartIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;repeat;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;repeat;(java.lang.String,java.lang.String,int);;Argument[1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replace;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replace;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceAll;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceAll;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceChars;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceChars;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[2].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[2].ArrayElement;ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnce;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnce;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnceIgnoreCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replaceOnceIgnoreCase;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replacePattern;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;replacePattern;;;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;reverse;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;reverseDelimited;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;right;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rightPad;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rightPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;rotate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,java.lang.String,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;split;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByCharacterType;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByCharacterTypeCamelCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByWholeSeparator;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitByWholeSeparatorPreserveAllTokens;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,java.lang.String,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;splitPreserveAllTokens;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripAccents;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripAll;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripEnd;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripStart;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripToEmpty;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;stripToNull;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substring;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringAfter;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringAfterLast;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBefore;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBeforeLast;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringBetween;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;substringsBetween;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toCodePoints;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toEncodedString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toRootLowerCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toRootUpperCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;toString;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trim;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trimToEmpty;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;trimToNull;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;truncate;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;uncapitalize;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;unwrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;upperCase;(java.lang.String,java.util.Locale);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;upperCase;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;valueOf;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrap;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrap;(java.lang.String,java.lang.String);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrapIfMissing;(java.lang.String,char);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3;StringUtils;false;wrapIfMissing;(java.lang.String,java.lang.String);;Argument[0..1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendAsObjectToString;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.mutable;Mutable;true;getValue;;;Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];ReturnValue;value;manual", - "org.apache.commons.lang3.mutable;MutableObject;false;MutableObject;;;Argument[0];Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];value;manual", - "org.apache.commons.lang3.mutable;Mutable;true;setValue;;;Argument[0];Argument[-1].SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value];value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.CharSequence,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.CharSequence);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;append;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterable);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterator);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Object[]);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder,int,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendln;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,int);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Argument[0].Element;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Object[],String);;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;asReader;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;asTokenizer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(char[]);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(char[]);;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;getChars;(int,int,char[],int);;Argument[-1];Argument[2];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;leftString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;midString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;readFrom;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;(int,int,java.lang.String);;Argument[2];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replace;(org.apache.commons.lang3.text.StrMatcher,java.lang.String,int,int,int);;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[1];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;rightString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrBuilder;false;StrBuilder;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;subSequence;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;substring;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toStringBuffer;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;toStringBuilder;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value;manual", - "org.apache.commons.lang3.text;StrLookup;false;lookup;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;Argument[0].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[],int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.CharSequence,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.CharSequence);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder);;Argument[-1];Argument[0];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;clone;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getContent;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getCSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTokenArray;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTokenList;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;getTSVInstance;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;next;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;nextToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;previous;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;previousToken;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;reset;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;reset;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;StrTokenizer;;;Argument[0];Argument[-1];taint;manual", - "org.apache.commons.lang3.text;StrTokenizer;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalizeFully;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;capitalizeFully;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;initials;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;initials;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;swapCase;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;uncapitalize;(java.lang.String,char[]);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;uncapitalize;(java.lang.String);;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;;;Argument[0];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean,java.lang.String);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3.text;WordUtils;false;wrap;(java.lang.String,int,java.lang.String,boolean);;Argument[2];ReturnValue;taint;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;left;;;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutablePair;false;right;;;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setLeft;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setRight;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutablePair;false;setValue;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setLeft;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setMiddle;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;MutableTriple;false;setRight;;;Argument[0];Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getKey;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getKey;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getValue;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;true;getValue;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutablePair.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.left];value;manual", - "org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutablePair.right];value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getMiddle;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getLeft;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.left];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getMiddle;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.middle];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;true;getRight;;;Argument[-1].Field[org.apache.commons.lang3.tuple.MutableTriple.right];ReturnValue;value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.left];value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle];value;manual", - "org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];ReturnValue.Field[org.apache.commons.lang3.tuple.ImmutableTriple.right];value;manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll deleted file mode 100644 index 4a9a6394aaf..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/apache/NegativeIOGenerated.qll +++ /dev/null @@ -1,769 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of negative summaries in the IOGenerated framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class IOGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.io.charset;CharsetDecoders;CharsetDecoders;();generated", - "org.apache.commons.io.charset;CharsetEncoders;CharsetEncoders;();generated", - "org.apache.commons.io.comparator;DefaultFileComparator;DefaultFileComparator;();generated", - "org.apache.commons.io.comparator;DirectoryFileComparator;DirectoryFileComparator;();generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;();generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;ExtensionFileComparator;toString;();generated", - "org.apache.commons.io.comparator;LastModifiedFileComparator;LastModifiedFileComparator;();generated", - "org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;();generated", - "org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;NameFileComparator;toString;();generated", - "org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;();generated", - "org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;(IOCase);generated", - "org.apache.commons.io.comparator;PathFileComparator;toString;();generated", - "org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;();generated", - "org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;(boolean);generated", - "org.apache.commons.io.comparator;SizeFileComparator;toString;();generated", - "org.apache.commons.io.file.attribute;FileTimes;minusMillis;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;minusNanos;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;minusSeconds;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;now;();generated", - "org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToDate;(long);generated", - "org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToFileTime;(long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusMillis;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusNanos;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;plusSeconds;(FileTime,long);generated", - "org.apache.commons.io.file.attribute;FileTimes;setLastModifiedTime;(Path);generated", - "org.apache.commons.io.file.attribute;FileTimes;toDate;(FileTime);generated", - "org.apache.commons.io.file.attribute;FileTimes;toFileTime;(Date);generated", - "org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(Date);generated", - "org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(FileTime);generated", - "org.apache.commons.io.file.spi;FileSystemProviders;getFileSystemProvider;(Path);generated", - "org.apache.commons.io.file.spi;FileSystemProviders;installed;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;AccumulatorPathVisitor;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;relativizeDirectories;(Path,boolean,Comparator);generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;relativizeFiles;(Path,boolean,Comparator);generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;AccumulatorPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;CleaningPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;CleaningPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;Counters$Counter;add;(long);generated", - "org.apache.commons.io.file;Counters$Counter;get;();generated", - "org.apache.commons.io.file;Counters$Counter;getBigInteger;();generated", - "org.apache.commons.io.file;Counters$Counter;getLong;();generated", - "org.apache.commons.io.file;Counters$Counter;increment;();generated", - "org.apache.commons.io.file;Counters$Counter;reset;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getByteCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getDirectoryCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;getFileCounter;();generated", - "org.apache.commons.io.file;Counters$PathCounters;reset;();generated", - "org.apache.commons.io.file;Counters;Counters;();generated", - "org.apache.commons.io.file;Counters;bigIntegerCounter;();generated", - "org.apache.commons.io.file;Counters;bigIntegerPathCounters;();generated", - "org.apache.commons.io.file;Counters;longCounter;();generated", - "org.apache.commons.io.file;Counters;longPathCounters;();generated", - "org.apache.commons.io.file;Counters;noopCounter;();generated", - "org.apache.commons.io.file;Counters;noopPathCounters;();generated", - "org.apache.commons.io.file;CountingPathVisitor;toString;();generated", - "org.apache.commons.io.file;CountingPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;CountingPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;DeletingPathVisitor;withBigIntegerCounters;();generated", - "org.apache.commons.io.file;DeletingPathVisitor;withLongCounters;();generated", - "org.apache.commons.io.file;NoopPathVisitor;NoopPathVisitor;();generated", - "org.apache.commons.io.file;PathFilter;accept;(Path,BasicFileAttributes);generated", - "org.apache.commons.io.file;PathUtils;cleanDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;cleanDirectory;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;copyDirectory;(Path,Path,CopyOption[]);generated", - "org.apache.commons.io.file;PathUtils;copyFileToDirectory;(Path,Path,CopyOption[]);generated", - "org.apache.commons.io.file;PathUtils;countDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;countDirectoryAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,FileAttribute[]);generated", - "org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,LinkOption,FileAttribute[]);generated", - "org.apache.commons.io.file;PathUtils;current;();generated", - "org.apache.commons.io.file;PathUtils;delete;(Path);generated", - "org.apache.commons.io.file;PathUtils;delete;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;delete;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path,DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;deleteFile;(Path,LinkOption[],DeleteOption[]);generated", - "org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path,LinkOption[],OpenOption[],FileVisitOption[]);generated", - "org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path,int,LinkOption[],FileVisitOption[]);generated", - "org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path,LinkOption[],OpenOption[]);generated", - "org.apache.commons.io.file;PathUtils;filter;(PathFilter,Path[]);generated", - "org.apache.commons.io.file;PathUtils;getAclEntryList;(Path);generated", - "org.apache.commons.io.file;PathUtils;getAclFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getDosFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getPosixFileAttributeView;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;getTempDirectory;();generated", - "org.apache.commons.io.file;PathUtils;isDirectory;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isEmpty;(Path);generated", - "org.apache.commons.io.file;PathUtils;isEmptyDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;isEmptyFile;(Path);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,ChronoZonedDateTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,FileTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,Instant,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;isNewer;(Path,long,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,FileTime,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,Instant,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;isOlder;(Path,long,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isPosix;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;isRegularFile;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;newDirectoryStream;(Path,PathFilter);generated", - "org.apache.commons.io.file;PathUtils;newOutputStream;(Path,boolean);generated", - "org.apache.commons.io.file;PathUtils;noFollowLinkOptionArray;();generated", - "org.apache.commons.io.file;PathUtils;readAttributes;(Path,Class,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readBasicFileAttributesUnchecked;(Path);generated", - "org.apache.commons.io.file;PathUtils;readDosFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readOsFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readPosixFileAttributes;(Path,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;readString;(Path,Charset);generated", - "org.apache.commons.io.file;PathUtils;setLastModifiedTime;(Path,Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOf;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfDirectory;(Path);generated", - "org.apache.commons.io.file;PathUtils;sizeOfDirectoryAsBigInteger;(Path);generated", - "org.apache.commons.io.file;PathUtils;waitFor;(Path,Duration,LinkOption[]);generated", - "org.apache.commons.io.file;PathUtils;walk;(Path,PathFilter,int,boolean,FileVisitOption[]);generated", - "org.apache.commons.io.file;StandardDeleteOption;overrideReadOnly;(DeleteOption[]);generated", - "org.apache.commons.io.filefilter;AbstractFileFilter;AbstractFileFilter;();generated", - "org.apache.commons.io.filefilter;AbstractFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date,boolean);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File,boolean);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;AndFileFilter;AndFileFilter;();generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;addFileFilter;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;getFileFilters;();generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;removeFileFilter;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;ConditionalFileFilter;setFileFilters;(List);generated", - "org.apache.commons.io.filefilter;FalseFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;FileFilterUtils;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;directoryFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;falseFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;fileFileFilter;();generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,File[]);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,Iterable);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;sizeRangeFileFilter;(long,long);generated", - "org.apache.commons.io.filefilter;FileFilterUtils;trueFileFilter;();generated", - "org.apache.commons.io.filefilter;IOFileFilter;and;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;IOFileFilter;negate;();generated", - "org.apache.commons.io.filefilter;IOFileFilter;or;(IOFileFilter);generated", - "org.apache.commons.io.filefilter;OrFileFilter;OrFileFilter;();generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String);generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,IOCase);generated", - "org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,int);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long,boolean);generated", - "org.apache.commons.io.filefilter;SizeFileFilter;toString;();generated", - "org.apache.commons.io.filefilter;SymbolicLinkFileFilter;SymbolicLinkFileFilter;(FileVisitResult,FileVisitResult);generated", - "org.apache.commons.io.filefilter;TrueFileFilter;toString;();generated", - "org.apache.commons.io.function;IOBiConsumer;accept;(Object,Object);generated", - "org.apache.commons.io.function;IOBiConsumer;andThen;(IOBiConsumer);generated", - "org.apache.commons.io.function;IOBiFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOBiFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOBiFunction;apply;(Object,Object);generated", - "org.apache.commons.io.function;IOConsumer;accept;(Object);generated", - "org.apache.commons.io.function;IOConsumer;andThen;(IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;forEach;(Object[],IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;forEachIndexed;(Stream,IOConsumer);generated", - "org.apache.commons.io.function;IOConsumer;noop;();generated", - "org.apache.commons.io.function;IOFunction;andThen;(Consumer);generated", - "org.apache.commons.io.function;IOFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOFunction;andThen;(IOConsumer);generated", - "org.apache.commons.io.function;IOFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOFunction;apply;(Object);generated", - "org.apache.commons.io.function;IOFunction;compose;(Function);generated", - "org.apache.commons.io.function;IOFunction;compose;(IOFunction);generated", - "org.apache.commons.io.function;IOFunction;compose;(IOSupplier);generated", - "org.apache.commons.io.function;IOFunction;compose;(Supplier);generated", - "org.apache.commons.io.function;IOFunction;identity;();generated", - "org.apache.commons.io.function;IORunnable;run;();generated", - "org.apache.commons.io.function;IOSupplier;get;();generated", - "org.apache.commons.io.function;IOTriFunction;andThen;(Function);generated", - "org.apache.commons.io.function;IOTriFunction;andThen;(IOFunction);generated", - "org.apache.commons.io.function;IOTriFunction;apply;(Object,Object,Object);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;(int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;clear;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;getCurrentNumberOfBytes;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;getSpace;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasBytes;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;(int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;peek;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;read;();generated", - "org.apache.commons.io.input.buffer;CircularByteBuffer;read;(byte[],int,int);generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[]);generated", - "org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[],int,int);generated", - "org.apache.commons.io.input;AutoCloseInputStream;AutoCloseInputStream;(InputStream);generated", - "org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream);generated", - "org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream,boolean);generated", - "org.apache.commons.io.input;BOMInputStream;hasBOM;();generated", - "org.apache.commons.io.input;BOMInputStream;hasBOM;(ByteOrderMark);generated", - "org.apache.commons.io.input;BoundedInputStream;isPropagateClose;();generated", - "org.apache.commons.io.input;BoundedInputStream;setPropagateClose;(boolean);generated", - "org.apache.commons.io.input;BoundedInputStream;toString;();generated", - "org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;();generated", - "org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;(IOException);generated", - "org.apache.commons.io.input;BrokenReader;BrokenReader;();generated", - "org.apache.commons.io.input;BrokenReader;BrokenReader;(IOException);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File,int);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path);generated", - "org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path,int);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset,int);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String);generated", - "org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String,int);generated", - "org.apache.commons.io.input;CharacterFilterReader;CharacterFilterReader;(Reader,int);generated", - "org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Integer[]);generated", - "org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Set);generated", - "org.apache.commons.io.input;CloseShieldInputStream;CloseShieldInputStream;(InputStream);generated", - "org.apache.commons.io.input;CloseShieldReader;CloseShieldReader;(Reader);generated", - "org.apache.commons.io.input;CloseShieldReader;wrap;(Reader);generated", - "org.apache.commons.io.input;ClosedInputStream;ClosedInputStream;();generated", - "org.apache.commons.io.input;ClosedReader;ClosedReader;();generated", - "org.apache.commons.io.input;CountingInputStream;CountingInputStream;(InputStream);generated", - "org.apache.commons.io.input;CountingInputStream;getByteCount;();generated", - "org.apache.commons.io.input;CountingInputStream;getCount;();generated", - "org.apache.commons.io.input;CountingInputStream;resetByteCount;();generated", - "org.apache.commons.io.input;CountingInputStream;resetCount;();generated", - "org.apache.commons.io.input;DemuxInputStream;DemuxInputStream;();generated", - "org.apache.commons.io.input;DemuxInputStream;bindStream;(InputStream);generated", - "org.apache.commons.io.input;MarkShieldInputStream;MarkShieldInputStream;(InputStream);generated", - "org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path);generated", - "org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path,int);generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream);generated", - "org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream,String);generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;();generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;(long);generated", - "org.apache.commons.io.input;NullInputStream;NullInputStream;(long,boolean,boolean);generated", - "org.apache.commons.io.input;NullInputStream;getPosition;();generated", - "org.apache.commons.io.input;NullInputStream;getSize;();generated", - "org.apache.commons.io.input;NullReader;NullReader;();generated", - "org.apache.commons.io.input;NullReader;NullReader;(long);generated", - "org.apache.commons.io.input;NullReader;NullReader;(long,boolean,boolean);generated", - "org.apache.commons.io.input;NullReader;getPosition;();generated", - "org.apache.commons.io.input;NullReader;getSize;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;Observer;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;closed;();generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;data;(byte[],int,int);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;data;(int);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;error;(IOException);generated", - "org.apache.commons.io.input;ObservableInputStream$Observer;finished;();generated", - "org.apache.commons.io.input;ObservableInputStream;ObservableInputStream;(InputStream);generated", - "org.apache.commons.io.input;ObservableInputStream;consume;();generated", - "org.apache.commons.io.input;ObservableInputStream;remove;(Observer);generated", - "org.apache.commons.io.input;ObservableInputStream;removeAllObservers;();generated", - "org.apache.commons.io.input;ProxyInputStream;ProxyInputStream;(InputStream);generated", - "org.apache.commons.io.input;ProxyReader;ProxyReader;(Reader);generated", - "org.apache.commons.io.input;QueueInputStream;QueueInputStream;();generated", - "org.apache.commons.io.input;QueueInputStream;QueueInputStream;(BlockingQueue);generated", - "org.apache.commons.io.input;QueueInputStream;newQueueOutputStream;();generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;availableLong;();generated", - "org.apache.commons.io.input;RandomAccessFileInputStream;isCloseOnClose;();generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,String);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,Charset);generated", - "org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,String);generated", - "org.apache.commons.io.input;SwappedDataInputStream;SwappedDataInputStream;(InputStream);generated", - "org.apache.commons.io.input;TaggedInputStream;TaggedInputStream;(InputStream);generated", - "org.apache.commons.io.input;TaggedInputStream;isCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedInputStream;throwIfCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedReader;TaggedReader;(Reader);generated", - "org.apache.commons.io.input;TaggedReader;isCauseOf;(Throwable);generated", - "org.apache.commons.io.input;TaggedReader;throwIfCauseOf;(Throwable);generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;getPointer;();generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;read;(byte[]);generated", - "org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;seek;(long);generated", - "org.apache.commons.io.input;Tailer$Tailable;getRandomAccess;(String);generated", - "org.apache.commons.io.input;Tailer$Tailable;isNewer;(FileTime);generated", - "org.apache.commons.io.input;Tailer$Tailable;lastModifiedFileTime;();generated", - "org.apache.commons.io.input;Tailer$Tailable;size;();generated", - "org.apache.commons.io.input;Tailer;getDelay;();generated", - "org.apache.commons.io.input;Tailer;stop;();generated", - "org.apache.commons.io.input;TailerListener;fileNotFound;();generated", - "org.apache.commons.io.input;TailerListener;fileRotated;();generated", - "org.apache.commons.io.input;TailerListener;handle;(Exception);generated", - "org.apache.commons.io.input;TailerListener;handle;(String);generated", - "org.apache.commons.io.input;TailerListener;init;(Tailer);generated", - "org.apache.commons.io.input;TailerListenerAdapter;TailerListenerAdapter;();generated", - "org.apache.commons.io.input;TailerListenerAdapter;endOfFileReached;();generated", - "org.apache.commons.io.input;TimestampedObserver;TimestampedObserver;();generated", - "org.apache.commons.io.input;TimestampedObserver;getOpenToCloseDuration;();generated", - "org.apache.commons.io.input;TimestampedObserver;getOpenToNowDuration;();generated", - "org.apache.commons.io.input;UncheckedFilterInputStream;UncheckedFilterInputStream;(InputStream);generated", - "org.apache.commons.io.input;UncheckedFilterReader;UncheckedFilterReader;(Reader);generated", - "org.apache.commons.io.input;UncheckedFilterReader;on;(Reader);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(File);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(Path);generated", - "org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(URL);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryChange;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryCreate;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onDirectoryDelete;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileChange;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileCreate;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onFileDelete;(File);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onStart;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationListener;onStop;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationListenerAdaptor;FileAlterationListenerAdaptor;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;(long);generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;getInterval;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;removeObserver;(FileAlterationObserver);generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;start;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;stop;();generated", - "org.apache.commons.io.monitor;FileAlterationMonitor;stop;(long);generated", - "org.apache.commons.io.monitor;FileAlterationObserver;checkAndNotify;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;destroy;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;initialize;();generated", - "org.apache.commons.io.monitor;FileAlterationObserver;removeListener;(FileAlterationListener);generated", - "org.apache.commons.io.monitor;FileEntry;getLastModified;();generated", - "org.apache.commons.io.monitor;FileEntry;getLength;();generated", - "org.apache.commons.io.monitor;FileEntry;getLevel;();generated", - "org.apache.commons.io.monitor;FileEntry;isDirectory;();generated", - "org.apache.commons.io.monitor;FileEntry;isExists;();generated", - "org.apache.commons.io.monitor;FileEntry;refresh;(File);generated", - "org.apache.commons.io.monitor;FileEntry;setDirectory;(boolean);generated", - "org.apache.commons.io.monitor;FileEntry;setExists;(boolean);generated", - "org.apache.commons.io.monitor;FileEntry;setLastModified;(long);generated", - "org.apache.commons.io.monitor;FileEntry;setLength;(long);generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;AbstractByteArrayOutputStream;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;reset;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;size;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;toByteArray;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;toInputStream;();generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;write;(InputStream);generated", - "org.apache.commons.io.output;AbstractByteArrayOutputStream;writeTo;(OutputStream);generated", - "org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;();generated", - "org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;(IOException);generated", - "org.apache.commons.io.output;BrokenWriter;BrokenWriter;();generated", - "org.apache.commons.io.output;BrokenWriter;BrokenWriter;(IOException);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;();generated", - "org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;(int);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer);generated", - "org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer,int);generated", - "org.apache.commons.io.output;CloseShieldWriter;CloseShieldWriter;(Writer);generated", - "org.apache.commons.io.output;CloseShieldWriter;wrap;(Writer);generated", - "org.apache.commons.io.output;ClosedOutputStream;ClosedOutputStream;();generated", - "org.apache.commons.io.output;ClosedWriter;ClosedWriter;();generated", - "org.apache.commons.io.output;CountingOutputStream;getByteCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;getCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;resetByteCount;();generated", - "org.apache.commons.io.output;CountingOutputStream;resetCount;();generated", - "org.apache.commons.io.output;DeferredFileOutputStream;isInMemory;();generated", - "org.apache.commons.io.output;DeferredFileOutputStream;toInputStream;();generated", - "org.apache.commons.io.output;DemuxOutputStream;DemuxOutputStream;();generated", - "org.apache.commons.io.output;DemuxOutputStream;bindStream;(OutputStream);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder,boolean);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String);generated", - "org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String,boolean);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,Charset);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,String);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,boolean);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String);generated", - "org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String,boolean);generated", - "org.apache.commons.io.output;NullOutputStream;NullOutputStream;();generated", - "org.apache.commons.io.output;NullPrintStream;NullPrintStream;();generated", - "org.apache.commons.io.output;NullWriter;NullWriter;();generated", - "org.apache.commons.io.output;ProxyWriter;ProxyWriter;(Writer);generated", - "org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;();generated", - "org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;(BlockingQueue);generated", - "org.apache.commons.io.output;QueueOutputStream;newQueueInputStream;();generated", - "org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;();generated", - "org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;(int);generated", - "org.apache.commons.io.output;TaggedOutputStream;isCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedOutputStream;throwIfCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedWriter;TaggedWriter;(Writer);generated", - "org.apache.commons.io.output;TaggedWriter;isCauseOf;(Exception);generated", - "org.apache.commons.io.output;TaggedWriter;throwIfCauseOf;(Exception);generated", - "org.apache.commons.io.output;ThresholdingOutputStream;ThresholdingOutputStream;(int);generated", - "org.apache.commons.io.output;ThresholdingOutputStream;getByteCount;();generated", - "org.apache.commons.io.output;ThresholdingOutputStream;getThreshold;();generated", - "org.apache.commons.io.output;ThresholdingOutputStream;isThresholdExceeded;();generated", - "org.apache.commons.io.output;UncheckedFilterWriter;on;(Writer);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;();generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;(int);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io.output;XmlStreamWriter;XmlStreamWriter;(File);generated", - "org.apache.commons.io.serialization;ClassNameMatcher;matches;(String);generated", - "org.apache.commons.io;ByteOrderMark;get;(int);generated", - "org.apache.commons.io;ByteOrderMark;getBytes;();generated", - "org.apache.commons.io;ByteOrderMark;length;();generated", - "org.apache.commons.io;ByteOrderParser;parseByteOrder;(String);generated", - "org.apache.commons.io;Charsets;Charsets;();generated", - "org.apache.commons.io;Charsets;requiredCharsets;();generated", - "org.apache.commons.io;Charsets;toCharset;(Charset);generated", - "org.apache.commons.io;Charsets;toCharset;(String);generated", - "org.apache.commons.io;CopyUtils;CopyUtils;();generated", - "org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream);generated", - "org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream,String);generated", - "org.apache.commons.io;CopyUtils;copy;(String,OutputStream);generated", - "org.apache.commons.io;CopyUtils;copy;(String,OutputStream,String);generated", - "org.apache.commons.io;DirectoryWalker$CancelException;getDepth;();generated", - "org.apache.commons.io;EndianUtils;EndianUtils;();generated", - "org.apache.commons.io;EndianUtils;readSwappedDouble;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedDouble;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedFloat;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedFloat;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedInteger;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedInteger;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedLong;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedLong;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedShort;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedShort;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(InputStream);generated", - "org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(byte[],int);generated", - "org.apache.commons.io;EndianUtils;swapDouble;(double);generated", - "org.apache.commons.io;EndianUtils;swapFloat;(float);generated", - "org.apache.commons.io;EndianUtils;swapInteger;(int);generated", - "org.apache.commons.io;EndianUtils;swapLong;(long);generated", - "org.apache.commons.io;EndianUtils;swapShort;(short);generated", - "org.apache.commons.io;EndianUtils;writeSwappedDouble;(OutputStream,double);generated", - "org.apache.commons.io;EndianUtils;writeSwappedDouble;(byte[],int,double);generated", - "org.apache.commons.io;EndianUtils;writeSwappedFloat;(OutputStream,float);generated", - "org.apache.commons.io;EndianUtils;writeSwappedFloat;(byte[],int,float);generated", - "org.apache.commons.io;EndianUtils;writeSwappedInteger;(OutputStream,int);generated", - "org.apache.commons.io;EndianUtils;writeSwappedInteger;(byte[],int,int);generated", - "org.apache.commons.io;EndianUtils;writeSwappedLong;(OutputStream,long);generated", - "org.apache.commons.io;EndianUtils;writeSwappedLong;(byte[],int,long);generated", - "org.apache.commons.io;EndianUtils;writeSwappedShort;(OutputStream,short);generated", - "org.apache.commons.io;EndianUtils;writeSwappedShort;(byte[],int,short);generated", - "org.apache.commons.io;FileCleaner;FileCleaner;();generated", - "org.apache.commons.io;FileCleaner;exitWhenFinished;();generated", - "org.apache.commons.io;FileCleaner;getInstance;();generated", - "org.apache.commons.io;FileCleaner;getTrackCount;();generated", - "org.apache.commons.io;FileCleaner;track;(File,Object);generated", - "org.apache.commons.io;FileCleaner;track;(File,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaner;track;(String,Object);generated", - "org.apache.commons.io;FileCleaner;track;(String,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaningTracker;FileCleaningTracker;();generated", - "org.apache.commons.io;FileCleaningTracker;exitWhenFinished;();generated", - "org.apache.commons.io;FileCleaningTracker;getTrackCount;();generated", - "org.apache.commons.io;FileCleaningTracker;track;(File,Object);generated", - "org.apache.commons.io;FileCleaningTracker;track;(File,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileCleaningTracker;track;(String,Object);generated", - "org.apache.commons.io;FileCleaningTracker;track;(String,Object,FileDeleteStrategy);generated", - "org.apache.commons.io;FileDeleteStrategy;delete;(File);generated", - "org.apache.commons.io;FileDeleteStrategy;deleteQuietly;(File);generated", - "org.apache.commons.io;FileExistsException;FileExistsException;();generated", - "org.apache.commons.io;FileExistsException;FileExistsException;(File);generated", - "org.apache.commons.io;FileExistsException;FileExistsException;(String);generated", - "org.apache.commons.io;FileSystem;getCurrent;();generated", - "org.apache.commons.io;FileSystem;getIllegalFileNameChars;();generated", - "org.apache.commons.io;FileSystem;getMaxFileNameLength;();generated", - "org.apache.commons.io;FileSystem;getMaxPathLength;();generated", - "org.apache.commons.io;FileSystem;getNameSeparator;();generated", - "org.apache.commons.io;FileSystem;getReservedFileNames;();generated", - "org.apache.commons.io;FileSystem;isCasePreserving;();generated", - "org.apache.commons.io;FileSystem;isCaseSensitive;();generated", - "org.apache.commons.io;FileSystem;isLegalFileName;(CharSequence);generated", - "org.apache.commons.io;FileSystem;isReservedFileName;(CharSequence);generated", - "org.apache.commons.io;FileSystem;normalizeSeparators;(String);generated", - "org.apache.commons.io;FileSystem;supportsDriveLetter;();generated", - "org.apache.commons.io;FileSystemUtils;FileSystemUtils;();generated", - "org.apache.commons.io;FileSystemUtils;freeSpace;(String);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;();generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String,long);generated", - "org.apache.commons.io;FileSystemUtils;freeSpaceKb;(long);generated", - "org.apache.commons.io;FileUtils;FileUtils;();generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(BigInteger);generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(Number);generated", - "org.apache.commons.io;FileUtils;byteCountToDisplaySize;(long);generated", - "org.apache.commons.io;FileUtils;checksumCRC32;(File);generated", - "org.apache.commons.io;FileUtils;cleanDirectory;(File);generated", - "org.apache.commons.io;FileUtils;contentEquals;(File,File);generated", - "org.apache.commons.io;FileUtils;contentEqualsIgnoreEOL;(File,File,String);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyDirectoryToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,File,boolean,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;copyFile;(File,OutputStream);generated", - "org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;copyInputStreamToFile;(InputStream,File);generated", - "org.apache.commons.io;FileUtils;copyToDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;copyToDirectory;(Iterable,File);generated", - "org.apache.commons.io;FileUtils;copyToFile;(InputStream,File);generated", - "org.apache.commons.io;FileUtils;copyURLToFile;(URL,File);generated", - "org.apache.commons.io;FileUtils;copyURLToFile;(URL,File,int,int);generated", - "org.apache.commons.io;FileUtils;createParentDirectories;(File);generated", - "org.apache.commons.io;FileUtils;current;();generated", - "org.apache.commons.io;FileUtils;deleteDirectory;(File);generated", - "org.apache.commons.io;FileUtils;deleteQuietly;(File);generated", - "org.apache.commons.io;FileUtils;directoryContains;(File,File);generated", - "org.apache.commons.io;FileUtils;forceDelete;(File);generated", - "org.apache.commons.io;FileUtils;forceDeleteOnExit;(File);generated", - "org.apache.commons.io;FileUtils;forceMkdir;(File);generated", - "org.apache.commons.io;FileUtils;forceMkdirParent;(File);generated", - "org.apache.commons.io;FileUtils;getTempDirectory;();generated", - "org.apache.commons.io;FileUtils;getTempDirectoryPath;();generated", - "org.apache.commons.io;FileUtils;getUserDirectory;();generated", - "org.apache.commons.io;FileUtils;getUserDirectoryPath;();generated", - "org.apache.commons.io;FileUtils;isDirectory;(File,LinkOption[]);generated", - "org.apache.commons.io;FileUtils;isEmptyDirectory;(File);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate,LocalTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime,ZoneId);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoZonedDateTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,Date);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,File);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,FileTime);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,Instant);generated", - "org.apache.commons.io;FileUtils;isFileNewer;(File,long);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate,LocalTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime,ZoneId);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoZonedDateTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,Date);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,File);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,FileTime);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,Instant);generated", - "org.apache.commons.io;FileUtils;isFileOlder;(File,long);generated", - "org.apache.commons.io;FileUtils;isRegularFile;(File,LinkOption[]);generated", - "org.apache.commons.io;FileUtils;isSymlink;(File);generated", - "org.apache.commons.io;FileUtils;iterateFiles;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;iterateFiles;(File,String[],boolean);generated", - "org.apache.commons.io;FileUtils;iterateFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;lastModified;(File);generated", - "org.apache.commons.io;FileUtils;lastModifiedFileTime;(File);generated", - "org.apache.commons.io;FileUtils;lastModifiedUnchecked;(File);generated", - "org.apache.commons.io;FileUtils;lineIterator;(File);generated", - "org.apache.commons.io;FileUtils;lineIterator;(File,String);generated", - "org.apache.commons.io;FileUtils;listFiles;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;listFiles;(File,String[],boolean);generated", - "org.apache.commons.io;FileUtils;listFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated", - "org.apache.commons.io;FileUtils;moveDirectory;(File,File);generated", - "org.apache.commons.io;FileUtils;moveDirectoryToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;moveFile;(File,File);generated", - "org.apache.commons.io;FileUtils;moveFile;(File,File,CopyOption[]);generated", - "org.apache.commons.io;FileUtils;moveFileToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;moveToDirectory;(File,File,boolean);generated", - "org.apache.commons.io;FileUtils;newOutputStream;(File,boolean);generated", - "org.apache.commons.io;FileUtils;openInputStream;(File);generated", - "org.apache.commons.io;FileUtils;openOutputStream;(File);generated", - "org.apache.commons.io;FileUtils;openOutputStream;(File,boolean);generated", - "org.apache.commons.io;FileUtils;readFileToByteArray;(File);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File,Charset);generated", - "org.apache.commons.io;FileUtils;readFileToString;(File,String);generated", - "org.apache.commons.io;FileUtils;readLines;(File);generated", - "org.apache.commons.io;FileUtils;readLines;(File,Charset);generated", - "org.apache.commons.io;FileUtils;readLines;(File,String);generated", - "org.apache.commons.io;FileUtils;sizeOf;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfAsBigInteger;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfDirectory;(File);generated", - "org.apache.commons.io;FileUtils;sizeOfDirectoryAsBigInteger;(File);generated", - "org.apache.commons.io;FileUtils;streamFiles;(File,boolean,String[]);generated", - "org.apache.commons.io;FileUtils;toFile;(URL);generated", - "org.apache.commons.io;FileUtils;toFiles;(URL[]);generated", - "org.apache.commons.io;FileUtils;touch;(File);generated", - "org.apache.commons.io;FileUtils;waitFor;(File,int);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset,boolean);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,String);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,String,boolean);generated", - "org.apache.commons.io;FileUtils;write;(File,CharSequence,boolean);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[]);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],boolean);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int);generated", - "org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,String);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,Collection,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String,boolean);generated", - "org.apache.commons.io;FileUtils;writeStringToFile;(File,String,boolean);generated", - "org.apache.commons.io;FilenameUtils;FilenameUtils;();generated", - "org.apache.commons.io;FilenameUtils;directoryContains;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equals;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equals;(String,String,boolean,IOCase);generated", - "org.apache.commons.io;FilenameUtils;equalsNormalized;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equalsNormalizedOnSystem;(String,String);generated", - "org.apache.commons.io;FilenameUtils;equalsOnSystem;(String,String);generated", - "org.apache.commons.io;FilenameUtils;getPrefixLength;(String);generated", - "org.apache.commons.io;FilenameUtils;indexOfExtension;(String);generated", - "org.apache.commons.io;FilenameUtils;indexOfLastSeparator;(String);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,Collection);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,String);generated", - "org.apache.commons.io;FilenameUtils;isExtension;(String,String[]);generated", - "org.apache.commons.io;FilenameUtils;separatorsToSystem;(String);generated", - "org.apache.commons.io;FilenameUtils;separatorsToUnix;(String);generated", - "org.apache.commons.io;FilenameUtils;separatorsToWindows;(String);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String,IOCase);generated", - "org.apache.commons.io;FilenameUtils;wildcardMatchOnSystem;(String,String);generated", - "org.apache.commons.io;HexDump;HexDump;();generated", - "org.apache.commons.io;HexDump;dump;(byte[],long,OutputStream,int);generated", - "org.apache.commons.io;IOCase;checkCompareTo;(String,String);generated", - "org.apache.commons.io;IOCase;checkEndsWith;(String,String);generated", - "org.apache.commons.io;IOCase;checkEquals;(String,String);generated", - "org.apache.commons.io;IOCase;checkIndexOf;(String,int,String);generated", - "org.apache.commons.io;IOCase;checkRegionMatches;(String,int,String);generated", - "org.apache.commons.io;IOCase;checkStartsWith;(String,String);generated", - "org.apache.commons.io;IOCase;forName;(String);generated", - "org.apache.commons.io;IOCase;getName;();generated", - "org.apache.commons.io;IOCase;isCaseSensitive;();generated", - "org.apache.commons.io;IOCase;isCaseSensitive;(IOCase);generated", - "org.apache.commons.io;IOCase;toString;();generated", - "org.apache.commons.io;IOCase;value;(IOCase,IOCase);generated", - "org.apache.commons.io;IOExceptionList;checkEmpty;(List,Object);generated", - "org.apache.commons.io;IOExceptionList;getCause;(int,Class);generated", - "org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(String,Throwable);generated", - "org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(Throwable);generated", - "org.apache.commons.io;IOIndexedException;IOIndexedException;(int,Throwable);generated", - "org.apache.commons.io;IOIndexedException;getIndex;();generated", - "org.apache.commons.io;IOUtils;IOUtils;();generated", - "org.apache.commons.io;IOUtils;byteArray;();generated", - "org.apache.commons.io;IOUtils;byteArray;(int);generated", - "org.apache.commons.io;IOUtils;close;(Closeable);generated", - "org.apache.commons.io;IOUtils;close;(Closeable,IOConsumer);generated", - "org.apache.commons.io;IOUtils;close;(Closeable[]);generated", - "org.apache.commons.io;IOUtils;close;(URLConnection);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable,Consumer);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Closeable[]);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(InputStream);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(OutputStream);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Reader);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Selector);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(ServerSocket);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Socket);generated", - "org.apache.commons.io;IOUtils;closeQuietly;(Writer);generated", - "org.apache.commons.io;IOUtils;consume;(InputStream);generated", - "org.apache.commons.io;IOUtils;contentEquals;(InputStream,InputStream);generated", - "org.apache.commons.io;IOUtils;contentEquals;(Reader,Reader);generated", - "org.apache.commons.io;IOUtils;contentEqualsIgnoreEOL;(Reader,Reader);generated", - "org.apache.commons.io;IOUtils;copy;(ByteArrayOutputStream);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;copy;(URL,File);generated", - "org.apache.commons.io;IOUtils;copy;(URL,OutputStream);generated", - "org.apache.commons.io;IOUtils;length;(CharSequence);generated", - "org.apache.commons.io;IOUtils;length;(Object[]);generated", - "org.apache.commons.io;IOUtils;length;(byte[]);generated", - "org.apache.commons.io;IOUtils;length;(char[]);generated", - "org.apache.commons.io;IOUtils;resourceToByteArray;(String);generated", - "org.apache.commons.io;IOUtils;resourceToByteArray;(String,ClassLoader);generated", - "org.apache.commons.io;IOUtils;resourceToString;(String,Charset);generated", - "org.apache.commons.io;IOUtils;resourceToString;(String,Charset,ClassLoader);generated", - "org.apache.commons.io;IOUtils;resourceToURL;(String);generated", - "org.apache.commons.io;IOUtils;resourceToURL;(String,ClassLoader);generated", - "org.apache.commons.io;IOUtils;skip;(InputStream,long);generated", - "org.apache.commons.io;IOUtils;skip;(ReadableByteChannel,long);generated", - "org.apache.commons.io;IOUtils;skip;(Reader,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(InputStream,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(ReadableByteChannel,long);generated", - "org.apache.commons.io;IOUtils;skipFully;(Reader,long);generated", - "org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream);generated", - "org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream,int);generated", - "org.apache.commons.io;IOUtils;toByteArray;(InputStream);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader,Charset);generated", - "org.apache.commons.io;IOUtils;toByteArray;(Reader,String);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URI);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URL);generated", - "org.apache.commons.io;IOUtils;toByteArray;(URLConnection);generated", - "org.apache.commons.io;IOUtils;toString;(URI);generated", - "org.apache.commons.io;IOUtils;toString;(URI,Charset);generated", - "org.apache.commons.io;IOUtils;toString;(URI,String);generated", - "org.apache.commons.io;IOUtils;toString;(URL);generated", - "org.apache.commons.io;IOUtils;toString;(URL,Charset);generated", - "org.apache.commons.io;IOUtils;toString;(URL,String);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(String,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream,String);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream,Charset);generated", - "org.apache.commons.io;IOUtils;write;(char[],OutputStream,String);generated", - "org.apache.commons.io;LineIterator;closeQuietly;(LineIterator);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(File);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(Path);generated", - "org.apache.commons.io;RandomAccessFileMode;create;(String);generated", - "org.apache.commons.io;RandomAccessFileMode;toString;();generated", - "org.apache.commons.io;StandardLineSeparator;getBytes;(Charset);generated", - "org.apache.commons.io;StandardLineSeparator;getString;();generated", - "org.apache.commons.io;TaggedIOException;isTaggedWith;(Throwable,Object);generated", - "org.apache.commons.io;TaggedIOException;throwCauseIfTaggedWith;(Throwable,Object);generated", - "org.apache.commons.io;UncheckedIO;UncheckedIO;();generated", - "org.apache.commons.io;UncheckedIO;accept;(IOConsumer,Object);generated", - "org.apache.commons.io;UncheckedIO;apply;(IOBiFunction,Object,Object);generated", - "org.apache.commons.io;UncheckedIO;get;(IOSupplier);generated", - "org.apache.commons.io;UncheckedIO;run;(IORunnable);generated", - "org.apache.commons.io;UncheckedIOExceptions;UncheckedIOExceptions;();generated", - "org.apache.commons.io;UncheckedIOExceptions;create;(Object);generated", - "org.apache.commons.io;UncheckedIOExceptions;wrap;(IOException,Object);generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/generated.qll b/java/ql/lib/semmle/code/java/frameworks/generated.qll deleted file mode 100644 index 7a16e24890e..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/generated.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * A module importing all generated Models as Data models. - */ - -import java - -private module GeneratedFrameworks { - private import apache.IOGenerated - private import kotlin.StdLibGenerated -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll deleted file mode 100644 index 424dade4291..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Base.qll +++ /dev/null @@ -1,98 +0,0 @@ -/** Definitions of flow steps through utility methods of `com.google.common.base`. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaBaseCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.base;Strings;false;emptyToNull;(String);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Strings;false;nullToEmpty;(String);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Strings;false;padStart;(String,int,char);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;padEnd;(String,int,char);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;repeat;(String,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;on;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;skipNulls;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;useForNull;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;withKeyValueSeparator;(char);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[1..2];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[3].ArrayElement;Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Iterable);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(Appendable,Iterator);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[1..2];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[3].ArrayElement;Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterable);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterator);;Argument[1].Element;Argument[-1];taint;manual", - "com.google.common.base;Joiner;false;appendTo;;;Argument[-1];Argument[0];taint;manual", - "com.google.common.base;Joiner;false;appendTo;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Joiner;false;join;;;Argument[-1..2];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[1];Argument[0];taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;Argument[0].Element.MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;Argument[0].Element.MapValue;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;Argument[0].Element.MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;Argument[0].Element.MapValue;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;Argument[0].MapKey;ReturnValue;taint;manual", - "com.google.common.base;Joiner$MapJoiner;false;join;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter;false;splitToStream;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Preconditions;false;checkNotNull;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Verify;false;verifyNotNull;;;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Ascii;false;toLowerCase;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toLowerCase;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toUpperCase;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;toUpperCase;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[2];ReturnValue;taint;manual", - "com.google.common.base;CaseFormat;true;to;(CaseFormat,String);;Argument[1];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;apply;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;convert;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Converter;true;convertAll;(Iterable);;Argument[0].Element;ReturnValue.Element;taint;manual", - "com.google.common.base;Supplier;true;get;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;ofInstance;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;memoize;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;memoizeWithExpiration;(Supplier,long,TimeUnit);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Suppliers;false;synchronizedSupplier;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Optional;true;fromJavaUtil;(Optional);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;fromNullable;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;get;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;asSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;of;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;or;(Optional);;Argument[-1..0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;or;(Supplier);;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;or;(Supplier);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;Optional;true;or;(Object);;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;or;(Object);;Argument[0];ReturnValue;value;manual", - "com.google.common.base;Optional;true;orNull;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.base;Optional;true;presentInstances;(Iterable);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;toJavaUtil;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.base;Optional;true;toJavaUtil;(Optional);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.base;MoreObjects;false;firstNonNull;(Object,Object);;Argument[0..1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects;false;toStringHelper;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];ReturnValue;taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];Argument[-1];taint;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;omitNullValues;();;Argument[-1];ReturnValue;value;manual", - "com.google.common.base;MoreObjects$ToStringHelper;false;toString;();;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll deleted file mode 100644 index d1f8cf4f776..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Cache.qll +++ /dev/null @@ -1,32 +0,0 @@ -/** Flow steps through methods of `com.google.common.cache` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaBaseCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.cache;Cache;true;asMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;asMap;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - // lambda flow from Argument[1] not implemented - "com.google.common.cache;Cache;true;get;(Object,Callable);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;Cache;true;getIfPresent;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - // the true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modeled fully accurately. - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.cache;Cache;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.cache;Cache;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.cache;Cache;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.cache;Cache;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.cache;LoadingCache;true;get;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;getUnchecked;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;apply;(Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[0].Element;Argument[-1].MapKey;value;manual", - "com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll index d662e7ee7cd..94dd356f62d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/Collections.qll @@ -3,577 +3,10 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.Collections private string guavaCollectPackage() { result = "com.google.common.collect" } -private class GuavaCollectCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - // Methods depending on lambda flow are not currently modeled - // Methods depending on stronger aliasing properties than we support are also not modeled. - "com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ArrayTable;true;create;(Iterable,Iterable);;Argument[0].Element;ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Iterable,Iterable);;Argument[1].Element;ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ArrayTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;BiMap;true;forcePut;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;BiMap;true;forcePut;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;BiMap;true;inverse;();;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - "com.google.common.collect;BiMap;true;inverse;();;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;getInstance;(Class);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;putInstance;(Class,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ClassToInstanceMap;true;putInstance;(Class,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Collections2;false;filter;(Collection,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Collections2;false;orderedPermutations;(Iterable);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Collections2;false;orderedPermutations;(Iterable,Comparator);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Collections2;false;permutations;(Collection);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;ConcurrentHashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;HashBasedTable;true;create;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;HashBiMap;true;create;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;HashBiMap;true;create;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;HashMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;HashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableBiMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;of;(Class,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableClassToInstanceMap;true;of;(Class,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;(Object);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;(Object[]);;Argument[0].ArrayElement;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;add;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;(Iterable);;Argument[0].Element;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;(Iterator);;Argument[0].Element;Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;addAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableCollection$Builder;true;build;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableCollection;true;asList;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;of;;;Argument[0..11];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;of;;;Argument[12].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;reverse;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;sortedCopyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableList;true;sortedCopyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableListMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;build;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;orderEntriesByValue;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;put;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMap$Builder;true;putAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;build;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;orderKeysBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;orderValuesBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Entry);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Entry);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;put;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Iterable);;Argument[0].Element.MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Multimap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Multimap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Object[]);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap$Builder;true;putAll;;;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;copyOf;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;inverse;();;Argument[-1].MapKey;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;inverse;();;Argument[-1].MapValue;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;addCopies;(Object,int);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;addCopies;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableMultiset$Builder;true;setCount;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableMultiset;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSet;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSetMultimap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable,Comparator);;Argument[0].Element.MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Iterable,Comparator);;Argument[0].Element.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map,Comparator);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOf;(Map,Comparator);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOfSorted;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;copyOfSorted;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[2];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[3];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[4];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[5];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[6];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[7];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[8];ReturnValue.MapKey;value;manual", - "com.google.common.collect;ImmutableSortedMap;true;of;;;Argument[9];ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparable[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Comparator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;copyOfSorted;(SortedMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedMultiset;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Collection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparable[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Collection);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Iterable);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Comparator,Iterator);;Argument[1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOf;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;copyOfSorted;(SortedSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;of;;;Argument[0..5];ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableSortedSet;true;of;;;Argument[6].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;build;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;orderColumnsBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;orderRowsBy;(Comparator);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Cell);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[0];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[1];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[-1];ReturnValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable$Builder;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable;true;copyOf;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[0];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[1];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;ImmutableTable;true;of;(Object,Object,Object);;Argument[2];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Iterables;false;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable,Iterable);;Argument[0..2].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable,Iterable,Iterable,Iterable);;Argument[0..3].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;concat;(Iterable[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;consumingIterable;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;cycle;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;cycle;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;filter;(Iterable,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;filter;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;find;(Iterable,Predicate,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;get;(Iterable,int,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getLast;(Iterable,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;getOnlyElement;(Iterable,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterables;false;limit;(Iterable,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;mergeSorted;(Iterable,Comparator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;paddedPartition;(Iterable,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterables;false;partition;(Iterable,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterables;false;skip;(Iterable,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;toArray;(Iterable,Class);;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - //"com.google.common.collect;Iterables;false;toString;(Iterable);;Element of Argument[0];ReturnValue;taint;manual", - "com.google.common.collect;Iterables;false;tryFind;(Iterable,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;unmodifiableIterable;(ImmutableCollection);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterables;false;unmodifiableIterable;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;addAll;(Collection,Iterator);;Argument[1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Iterators;false;asEnumeration;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator,Iterator);;Argument[0..2].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator,Iterator,Iterator,Iterator);;Argument[0..3].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;concat;(Iterator[]);;Argument[0].ArrayElement.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;consumingIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;cycle;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;cycle;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;filter;(Iterator,Class);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;filter;(Iterator,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;find;(Iterator,Predicate,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;forArray;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;forEnumeration;(Enumeration);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int,Object);;Argument[2];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;get;(Iterator,int,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getLast;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getNext;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getNext;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator,Object);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;getOnlyElement;(Iterator,Object);;Argument[0].Element;ReturnValue;value;manual", - "com.google.common.collect;Iterators;false;limit;(Iterator,int);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;mergeSorted;(Iterable,Comparator);;Argument[0].Element.Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;paddedPartition;(Iterator,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterators;false;partition;(Iterator,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Iterators;false;peekingIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;peekingIterator;(PeekingIterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;singletonIterator;(Object);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;toArray;(Iterator,Class);;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;Iterators;false;tryFind;(Iterator,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;unmodifiableIterator;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Iterators;false;unmodifiableIterator;(UnmodifiableIterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;LinkedHashMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;LinkedHashMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;LinkedHashMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;LinkedListMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;LinkedListMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object,Object[]);;Argument[0..1];ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object,Object[]);;Argument[2].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object[]);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;asList;(Object,Object[]);;Argument[1].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;cartesianProduct;(List);;Argument[0].Element.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;cartesianProduct;(List[]);;Argument[0].ArrayElement.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;charactersOf;(CharSequence);;Argument[0];ReturnValue.Element;taint;manual", - "com.google.common.collect;Lists;false;charactersOf;(String);;Argument[0];ReturnValue.Element;taint;manual", - "com.google.common.collect;Lists;false;newArrayList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newArrayList;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newArrayList;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newCopyOnWriteArrayList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;newLinkedList;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Lists;false;partition;(List,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Lists;false;reverse;(List);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;MapDifference$ValueDifference;true;leftValue;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left];ReturnValue;value;manual", - "com.google.common.collect;MapDifference$ValueDifference;true;rightValue;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right];ReturnValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.left];value;manual", - "com.google.common.collect;MapDifference;true;entriesDiffering;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue.SyntheticField[com.google.common.collect.MapDifference.right];value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesInCommon;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnLeft;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnLeft;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.left].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnRight;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MapDifference;true;entriesOnlyOnRight;();;Argument[-1].SyntheticField[com.google.common.collect.MapDifference.right].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;asMap;(NavigableSet,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;asMap;(Set,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;asMap;(SortedSet,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(Map,Map,Equivalence);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[1].MapKey;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapKey;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[0].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.left].MapValue;value;manual", - "com.google.common.collect;Maps;false;difference;(SortedMap,Map);;Argument[1].MapValue;ReturnValue.SyntheticField[com.google.common.collect.MapDifference.right].MapValue;value;manual", - "com.google.common.collect;Maps;false;filterEntries;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;filterKeys;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;filterValues;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;fromProperties;(Properties);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;fromProperties;(Properties);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;immutableEntry;(Object,Object);;Argument[0];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;immutableEntry;(Object,Object);;Argument[1];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;immutableEnumMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newEnumMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newHashMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newHashMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newLinkedHashMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newLinkedHashMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;newTreeMap;(SortedMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;newTreeMap;(SortedMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;subMap;(NavigableMap,Range);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;subMap;(NavigableMap,Range);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;synchronizedBiMap;(BiMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;synchronizedBiMap;(BiMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;synchronizedNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;toMap;(Iterable,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;toMap;(Iterator,Function);;Argument[0].Element;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(Map,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(NavigableMap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;transformValues;(SortedMap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;uniqueIndex;(Iterable,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;uniqueIndex;(Iterator,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;unmodifiableBiMap;(BiMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;unmodifiableBiMap;(BiMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Maps;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Maps;false;unmodifiableNavigableMap;(NavigableMap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimap;true;asMap;();;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimap;true;asMap;();;Argument[-1].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimap;true;entries;();;Argument[-1].MapKey;ReturnValue.Element.MapKey;value;manual", - "com.google.common.collect;Multimap;true;entries;();;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "com.google.common.collect;Multimap;true;get;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;keySet;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;keys;();;Argument[-1].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;put;(Object,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;put;(Object,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Multimap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Multimap);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;putAll;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;removeAll;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[0];Argument[-1].MapKey;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[1].Element;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Multimap;true;replaceValues;(Object,Iterable);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimap;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;asMap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue.Element;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterEntries;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterKeys;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(Multimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(Multimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(SetMultimap,Predicate);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;filterValues;(SetMultimap,Predicate);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;forMap;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;forMap;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;index;(Iterable,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;index;(Iterator,Function);;Argument[0].Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[1];ReturnValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[0].MapKey;Argument[1].MapValue;value;manual", - "com.google.common.collect;Multimaps;false;invertFrom;(Multimap,Multimap);;Argument[0].MapValue;Argument[1].MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newListMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newListMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newSetMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newSetMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;newSortedSetMultimap;(Map,Supplier);;Argument[0].MapValue.Element;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;newSortedSetMultimap;(Map,Supplier);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedListMultimap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedListMultimap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedMultimap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedMultimap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSetMultimap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSetMultimap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;synchronizedSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;transformValues;(ListMultimap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;transformValues;(Multimap,Function);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ImmutableListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ImmutableListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ListMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableListMultimap;(ListMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(ImmutableMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(ImmutableMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableMultimap;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(ImmutableSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(ImmutableSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(SetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSetMultimap;(SetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;Multimaps;false;unmodifiableSortedSetMultimap;(SortedSetMultimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Multiset$Entry;true;getElement;();;Argument[-1].Element;ReturnValue;value;manual", - "com.google.common.collect;Multiset;true;add;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multiset;true;elementSet;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multiset;true;entrySet;();;Argument[-1].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Multiset;true;setCount;(Object,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multiset;true;setCount;(Object,int,int);;Argument[0];Argument[-1].Element;value;manual", - "com.google.common.collect;Multisets;false;copyHighestCountFirst;(Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;difference;(Multiset,Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;filter;(Multiset,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;immutableEntry;(Object,int);;Argument[0];ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;intersection;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;sum;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;union;(Multiset,Multiset);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableMultiset;(ImmutableMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableMultiset;(Multiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Multisets;false;unmodifiableSortedMultiset;(SortedMultiset);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;MutableClassToInstanceMap;true;create;(Map);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;MutableClassToInstanceMap;true;create;(Map);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object,Object[]);;Argument[0];ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object,Object[]);;Argument[1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object);;Argument[1];ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object);;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;ObjectArrays;false;concat;(Object[],Object[],Class);;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "com.google.common.collect;Queues;false;drain;(BlockingQueue,Collection,int,Duration);;Argument[0].Element;Argument[1].Element;value;manual", - "com.google.common.collect;Queues;false;drain;(BlockingQueue,Collection,int,long,TimeUnit);;Argument[0].Element;Argument[1].Element;value;manual", - "com.google.common.collect;Queues;false;newArrayDeque;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newConcurrentLinkedQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newLinkedBlockingDeque;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newLinkedBlockingQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newPriorityBlockingQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;newPriorityQueue;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;synchronizedDeque;(Deque);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Queues;false;synchronizedQueue;(Queue);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets$SetView;true;copyInto;(Set);;Argument[-1].Element;Argument[0].Element;value;manual", - "com.google.common.collect;Sets$SetView;true;immutableCopy;();;Argument[-1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;cartesianProduct;(List);;Argument[0].Element.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;cartesianProduct;(Set[]);;Argument[0].ArrayElement.Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;combinations;(Set,int);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;difference;(Set,Set);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(NavigableSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(Set,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;filter;(SortedSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;intersection;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newCopyOnWriteArraySet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newHashSet;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newLinkedHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newSetFromMap;(Map);;Argument[0].MapKey;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;newTreeSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;powerSet;(Set);;Argument[0].Element;ReturnValue.Element.Element;value;manual", - "com.google.common.collect;Sets;false;subSet;(NavigableSet,Range);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;symmetricDifference;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;synchronizedNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;union;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Sets;false;unmodifiableNavigableSet;(NavigableSet);;Argument[0].Element;ReturnValue.Element;value;manual", - "com.google.common.collect;Table$Cell;true;getColumnKey;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue;value;manual", - "com.google.common.collect;Table$Cell;true;getRowKey;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue;value;manual", - "com.google.common.collect;Table$Cell;true;getValue;();;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].MapValue;ReturnValue.Element.MapValue;value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.Element.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;cellSet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.Element.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;column;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Table;true;column;(Object);;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;columnKeySet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.Element;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].MapValue;ReturnValue.MapValue.MapValue;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;columnMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapValue.MapKey;value;manual", - "com.google.common.collect;Table;true;get;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[0];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[1];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;put;(Object,Object,Object);;Argument[2];Argument[-1].MapValue;value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Table;true;putAll;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Table;true;remove;(Object,Object);;Argument[-1].MapValue;ReturnValue;value;manual", - "com.google.common.collect;Table;true;row;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Table;true;row;(Object);;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;rowKeySet;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.Element;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].MapValue;ReturnValue.MapValue.MapValue;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.MapValue.MapKey;value;manual", - "com.google.common.collect;Table;true;rowMap;();;Argument[-1].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.MapKey;value;manual", - "com.google.common.collect;Table;true;values;();;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[0];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[1];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;immutableCell;(Object,Object,Object);;Argument[2];ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapKey;ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapValue.MapKey;ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;newCustomTable;(Map,Supplier);;Argument[0].MapValue.MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;synchronizedTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transformValues;(Table,Function);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;transformValues;(Table,Function);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;transpose;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableRowSortedTable;(RowSortedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;Tables;false;unmodifiableTable;(Table);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.columnKey];ReturnValue.SyntheticField[com.google.common.collect.Table.columnKey];value;manual", - "com.google.common.collect;TreeBasedTable;true;create;(TreeBasedTable);;Argument[0].SyntheticField[com.google.common.collect.Table.rowKey];ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual", - "com.google.common.collect;TreeMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "com.google.common.collect;TreeMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "com.google.common.collect;TreeMultiset;true;create;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual" - ] - } -} - /** * A reference type that extends a parameterization of `com.google.common.collect.Multimap`. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll b/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll index d7a4ab959df..5dd8aaa18ee 100644 --- a/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll +++ b/java/ql/lib/semmle/code/java/frameworks/guava/Guava.qll @@ -3,7 +3,4 @@ */ import java -import Base import Collections -import IO -import Cache diff --git a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll b/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll deleted file mode 100644 index 6137a4e47f3..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/guava/IO.qll +++ /dev/null @@ -1,102 +0,0 @@ -/** Definitions of taint steps in the IO package of the Guava framework */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class GuavaIoCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;withSeparator;(String,int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;upperCase;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;lowerCase;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;withPadChar;(char);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(ByteSource[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(Iterable);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;concat;(Iterator);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;copyTo;(OutputStream);;Argument[-1];Argument[0];taint;manual", - "com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;read;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;slice;(long,long);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteSource;true;wrap;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;copy;(ReadableByteChannel,WritableByteChannel);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;limit;(InputStream,long);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(byte[]);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(byte[],int);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataInput;(ByteArrayInputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;newDataOutput;(ByteArrayOutputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;ByteStreams;false;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(CharSource[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(Iterable);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;concat;(Iterator);;Argument[0].Element;ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint;manual", - "com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;read;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;readFirstLine;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;readLines;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;lines;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;CharSource;true;wrap;(CharSequence);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharStreams;false;copy;(Readable,Appendable);;Argument[0];Argument[1];taint;manual", - "com.google.common.io;CharStreams;false;readLines;(Readable);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;CharStreams;false;toString;(Readable);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Closer;true;register;;;Argument[0];ReturnValue;value;manual", - "com.google.common.io;Files;false;getFileExtension;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Files;false;getNameWithoutExtension;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;Files;false;simplifyPath;(String);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;MoreFiles;false;getFileExtension;(Path);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;MoreFiles;false;getNameWithoutExtension;(Path);;Argument[0];ReturnValue;taint;manual", - "com.google.common.io;LineReader;false;LineReader;(Readable);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;LineReader;true;readLine;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;toByteArray;();;Argument[-1];ReturnValue;taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(byte[]);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;write;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeByte;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeBytes;(String);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeChar;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeChars;(String);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeDouble;(double);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeFloat;(float);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeInt;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeLong;(long);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeShort;(int);;Argument[0];Argument[-1];taint;manual", - "com.google.common.io;ByteArrayDataOutput;true;writeUTF;(String);;Argument[0];Argument[-1];taint;manual" - ] - } -} - -private class GuavaIoSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; kind` - "com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;readLines;;;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;toByteArray;(URL);;Argument[0];url-open-stream;manual", - "com.google.common.io;Resources;false;toString;(URL,Charset);;Argument[0];url-open-stream;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll index 20a7303dd76..2aa78e9425d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jOOQ.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow /** * Methods annotated with this allow for generation of "plain SQL" @@ -22,9 +21,3 @@ predicate jOOQSqlMethod(Method m) { m.getAnAnnotation() instanceof PlainSqlType and m.getParameterType(0) instanceof TypeString } - -private class SqlSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = "org.jooq;PlainSQL;false;;;Annotated;Argument[0];sql;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index 400f96598c1..020c167fab7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -9,7 +9,6 @@ import semmle.code.java.Reflection import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.internal.DataFlowForSerializability import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow /** * A `@com.fasterxml.jackson.annotation.JsonIgnore` annoation. @@ -282,18 +281,3 @@ class JacksonMixedInCallable extends Callable { ) } } - -private class JacksonModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0].MapValue;ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0].MapValue.Element;ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;true;convertValue;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectMapper;false;createParser;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.databind;ObjectReader;false;createParser;;;Argument[0];ReturnValue;taint;manual", - "com.fasterxml.jackson.core;JsonFactory;false;createParser;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll index 23e1518c916..c56571624e6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll @@ -75,14 +75,11 @@ class ForbiddenSecurityConfigurationCallable extends ForbiddenCallable { } /** A method or constructor involving serialization that may not be called by an EJB. */ -class ForbiddenSerializationCallable extends ForbiddenCallable { - ForbiddenSerializationCallable() { this instanceof ForbiddenSerializationMethod } +class ForbiddenSerializationCallable extends ForbiddenCallable instanceof ForbiddenSerializationMethod { } /** A method or constructor involving network factory operations that may not be called by an EJB. */ -class ForbiddenSetFactoryCallable extends ForbiddenCallable { - ForbiddenSetFactoryCallable() { this instanceof ForbiddenSetFactoryMethod } -} +class ForbiddenSetFactoryCallable extends ForbiddenCallable instanceof ForbiddenSetFactoryMethod { } /** A method or constructor involving server socket operations that may not be called by an EJB. */ class ForbiddenServerSocketCallable extends ForbiddenCallable { diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll index 9efa891676b..546d3be6983 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFRenderer.qll @@ -1,7 +1,6 @@ /** Provides classes and predicates for working with JavaServer Faces renderer. */ import java -private import semmle.code.java.dataflow.ExternalFlow /** * The JSF class `FacesContext` for processing HTTP requests. @@ -12,22 +11,6 @@ class FacesContext extends RefType { } } -private class ExternalContextSource extends SourceModelCsv { - override predicate row(string row) { - row = - ["javax.", "jakarta."] + - [ - "faces.context;ExternalContext;true;getRequestParameterMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestParameterNames;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestParameterValuesMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestPathInfo;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestCookieMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestHeaderMap;();;ReturnValue;remote;manual", - "faces.context;ExternalContext;true;getRequestHeaderValuesMap;();;ReturnValue;remote;manual" - ] - } -} - /** * The method `getResponseWriter()` declared in JSF `ExternalContext`. */ @@ -49,15 +32,3 @@ class FacesGetResponseStreamMethod extends Method { this.getNumberOfParameters() = 0 } } - -private class ExternalContextXssSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.faces.context;ResponseWriter;true;write;;;Argument[0];xss;manual", - "javax.faces.context;ResponseStream;true;write;;;Argument[0];xss;manual", - "jakarta.faces.context;ResponseWriter;true;write;;;Argument[0];xss;manual", - "jakarta.faces.context;ResponseStream;true;write;;;Argument[0];xss;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/IO.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/IO.qll new file mode 100644 index 00000000000..38af34bc690 --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/IO.qll @@ -0,0 +1,8 @@ +/** Provides classes and predicates related to `kotlin.io`. */ + +import java + +/** The type `kotlin.io.FilesKt`, where `File` extension methods are declared. */ +class FilesKt extends RefType { + FilesKt() { this.hasQualifiedName("kotlin.io", "FilesKt") } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll deleted file mode 100644 index 412390f139e..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/NegativeStdLibGenerated.qll +++ /dev/null @@ -1,4414 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of negative summaries in the Kotlin StdLib @30ce58cea74 framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StdLibGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.annotation;AnnotationRetention;valueOf;(String);generated", - "kotlin.annotation;AnnotationRetention;values;();generated", - "kotlin.annotation;AnnotationTarget;valueOf;(String);generated", - "kotlin.annotation;AnnotationTarget;values;();generated", - "kotlin.annotation;MustBeDocumented;MustBeDocumented;();generated", - "kotlin.annotation;Repeatable;Repeatable;();generated", - "kotlin.annotation;Retention;Retention;(AnnotationRetention);generated", - "kotlin.annotation;Retention;value;();generated", - "kotlin.annotation;Target;Target;(AnnotationTarget[]);generated", - "kotlin.annotation;Target;allowedTargets;();generated", - "kotlin.collections.builders;SerializedCollection$Companion;getTagList;();generated", - "kotlin.collections.builders;SerializedCollection$Companion;getTagSet;();generated", - "kotlin.collections;AbstractIterator;AbstractIterator;();generated", - "kotlin.collections;AbstractList;equals;(Object);generated", - "kotlin.collections;AbstractList;hashCode;();generated", - "kotlin.collections;AbstractMap;equals;(Object);generated", - "kotlin.collections;AbstractMap;hashCode;();generated", - "kotlin.collections;AbstractMap;toString;();generated", - "kotlin.collections;AbstractSet;equals;(Object);generated", - "kotlin.collections;AbstractSet;hashCode;();generated", - "kotlin.collections;ArrayDeque;ArrayDeque;();generated", - "kotlin.collections;ArrayDeque;ArrayDeque;(int);generated", - "kotlin.collections;ArrayList;ArrayList;();generated", - "kotlin.collections;ArrayList;ArrayList;(Collection);generated", - "kotlin.collections;ArrayList;ArrayList;(int);generated", - "kotlin.collections;ArrayList;ensureCapacity;(int);generated", - "kotlin.collections;ArrayList;trimToSize;();generated", - "kotlin.collections;ArraysKt;all;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;all;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;all;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;all;(char[],Function1);generated", - "kotlin.collections;ArraysKt;all;(double[],Function1);generated", - "kotlin.collections;ArraysKt;all;(float[],Function1);generated", - "kotlin.collections;ArraysKt;all;(int[],Function1);generated", - "kotlin.collections;ArraysKt;all;(long[],Function1);generated", - "kotlin.collections;ArraysKt;all;(short[],Function1);generated", - "kotlin.collections;ArraysKt;any;(Object[]);generated", - "kotlin.collections;ArraysKt;any;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;any;(boolean[]);generated", - "kotlin.collections;ArraysKt;any;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;any;(byte[]);generated", - "kotlin.collections;ArraysKt;any;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;any;(char[]);generated", - "kotlin.collections;ArraysKt;any;(char[],Function1);generated", - "kotlin.collections;ArraysKt;any;(double[]);generated", - "kotlin.collections;ArraysKt;any;(double[],Function1);generated", - "kotlin.collections;ArraysKt;any;(float[]);generated", - "kotlin.collections;ArraysKt;any;(float[],Function1);generated", - "kotlin.collections;ArraysKt;any;(int[]);generated", - "kotlin.collections;ArraysKt;any;(int[],Function1);generated", - "kotlin.collections;ArraysKt;any;(long[]);generated", - "kotlin.collections;ArraysKt;any;(long[],Function1);generated", - "kotlin.collections;ArraysKt;any;(short[]);generated", - "kotlin.collections;ArraysKt;any;(short[],Function1);generated", - "kotlin.collections;ArraysKt;asIterable;(Object[]);generated", - "kotlin.collections;ArraysKt;asIterable;(boolean[]);generated", - "kotlin.collections;ArraysKt;asIterable;(byte[]);generated", - "kotlin.collections;ArraysKt;asIterable;(char[]);generated", - "kotlin.collections;ArraysKt;asIterable;(double[]);generated", - "kotlin.collections;ArraysKt;asIterable;(float[]);generated", - "kotlin.collections;ArraysKt;asIterable;(int[]);generated", - "kotlin.collections;ArraysKt;asIterable;(long[]);generated", - "kotlin.collections;ArraysKt;asIterable;(short[]);generated", - "kotlin.collections;ArraysKt;asList;(boolean[]);generated", - "kotlin.collections;ArraysKt;asList;(byte[]);generated", - "kotlin.collections;ArraysKt;asList;(char[]);generated", - "kotlin.collections;ArraysKt;asList;(double[]);generated", - "kotlin.collections;ArraysKt;asList;(float[]);generated", - "kotlin.collections;ArraysKt;asList;(int[]);generated", - "kotlin.collections;ArraysKt;asList;(long[]);generated", - "kotlin.collections;ArraysKt;asList;(short[]);generated", - "kotlin.collections;ArraysKt;asSequence;(Object[]);generated", - "kotlin.collections;ArraysKt;asSequence;(boolean[]);generated", - "kotlin.collections;ArraysKt;asSequence;(byte[]);generated", - "kotlin.collections;ArraysKt;asSequence;(char[]);generated", - "kotlin.collections;ArraysKt;asSequence;(double[]);generated", - "kotlin.collections;ArraysKt;asSequence;(float[]);generated", - "kotlin.collections;ArraysKt;asSequence;(int[]);generated", - "kotlin.collections;ArraysKt;asSequence;(long[]);generated", - "kotlin.collections;ArraysKt;asSequence;(short[]);generated", - "kotlin.collections;ArraysKt;associate;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associate;(short[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(Object[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(boolean[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(byte[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(char[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(double[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(float[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(int[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(long[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;associateBy;(short[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(char[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(double[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(float[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(int[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(long[],Function1);generated", - "kotlin.collections;ArraysKt;associateWith;(short[],Function1);generated", - "kotlin.collections;ArraysKt;average;(byte[]);generated", - "kotlin.collections;ArraysKt;average;(double[]);generated", - "kotlin.collections;ArraysKt;average;(float[]);generated", - "kotlin.collections;ArraysKt;average;(int[]);generated", - "kotlin.collections;ArraysKt;average;(long[]);generated", - "kotlin.collections;ArraysKt;average;(short[]);generated", - "kotlin.collections;ArraysKt;averageOfByte;(Byte[]);generated", - "kotlin.collections;ArraysKt;averageOfDouble;(Double[]);generated", - "kotlin.collections;ArraysKt;averageOfFloat;(Float[]);generated", - "kotlin.collections;ArraysKt;averageOfInt;(Integer[]);generated", - "kotlin.collections;ArraysKt;averageOfLong;(Long[]);generated", - "kotlin.collections;ArraysKt;averageOfShort;(Short[]);generated", - "kotlin.collections;ArraysKt;binarySearch;(Object[],Object,Comparator,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(Object[],Object,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(byte[],byte,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(char[],char,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(double[],double,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(float[],float,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(int[],int,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(long[],long,int,int);generated", - "kotlin.collections;ArraysKt;binarySearch;(short[],short,int,int);generated", - "kotlin.collections;ArraysKt;component1;(Object[]);generated", - "kotlin.collections;ArraysKt;component1;(boolean[]);generated", - "kotlin.collections;ArraysKt;component1;(byte[]);generated", - "kotlin.collections;ArraysKt;component1;(char[]);generated", - "kotlin.collections;ArraysKt;component1;(double[]);generated", - "kotlin.collections;ArraysKt;component1;(float[]);generated", - "kotlin.collections;ArraysKt;component1;(int[]);generated", - "kotlin.collections;ArraysKt;component1;(long[]);generated", - "kotlin.collections;ArraysKt;component1;(short[]);generated", - "kotlin.collections;ArraysKt;component2;(Object[]);generated", - "kotlin.collections;ArraysKt;component2;(boolean[]);generated", - "kotlin.collections;ArraysKt;component2;(byte[]);generated", - "kotlin.collections;ArraysKt;component2;(char[]);generated", - "kotlin.collections;ArraysKt;component2;(double[]);generated", - "kotlin.collections;ArraysKt;component2;(float[]);generated", - "kotlin.collections;ArraysKt;component2;(int[]);generated", - "kotlin.collections;ArraysKt;component2;(long[]);generated", - "kotlin.collections;ArraysKt;component2;(short[]);generated", - "kotlin.collections;ArraysKt;component3;(Object[]);generated", - "kotlin.collections;ArraysKt;component3;(boolean[]);generated", - "kotlin.collections;ArraysKt;component3;(byte[]);generated", - "kotlin.collections;ArraysKt;component3;(char[]);generated", - "kotlin.collections;ArraysKt;component3;(double[]);generated", - "kotlin.collections;ArraysKt;component3;(float[]);generated", - "kotlin.collections;ArraysKt;component3;(int[]);generated", - "kotlin.collections;ArraysKt;component3;(long[]);generated", - "kotlin.collections;ArraysKt;component3;(short[]);generated", - "kotlin.collections;ArraysKt;component4;(Object[]);generated", - "kotlin.collections;ArraysKt;component4;(boolean[]);generated", - "kotlin.collections;ArraysKt;component4;(byte[]);generated", - "kotlin.collections;ArraysKt;component4;(char[]);generated", - "kotlin.collections;ArraysKt;component4;(double[]);generated", - "kotlin.collections;ArraysKt;component4;(float[]);generated", - "kotlin.collections;ArraysKt;component4;(int[]);generated", - "kotlin.collections;ArraysKt;component4;(long[]);generated", - "kotlin.collections;ArraysKt;component4;(short[]);generated", - "kotlin.collections;ArraysKt;component5;(Object[]);generated", - "kotlin.collections;ArraysKt;component5;(boolean[]);generated", - "kotlin.collections;ArraysKt;component5;(byte[]);generated", - "kotlin.collections;ArraysKt;component5;(char[]);generated", - "kotlin.collections;ArraysKt;component5;(double[]);generated", - "kotlin.collections;ArraysKt;component5;(float[]);generated", - "kotlin.collections;ArraysKt;component5;(int[]);generated", - "kotlin.collections;ArraysKt;component5;(long[]);generated", - "kotlin.collections;ArraysKt;component5;(short[]);generated", - "kotlin.collections;ArraysKt;contains;(Object[],Object);generated", - "kotlin.collections;ArraysKt;contains;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;contains;(byte[],byte);generated", - "kotlin.collections;ArraysKt;contains;(char[],char);generated", - "kotlin.collections;ArraysKt;contains;(double[],double);generated", - "kotlin.collections;ArraysKt;contains;(float[],float);generated", - "kotlin.collections;ArraysKt;contains;(int[],int);generated", - "kotlin.collections;ArraysKt;contains;(long[],long);generated", - "kotlin.collections;ArraysKt;contains;(short[],short);generated", - "kotlin.collections;ArraysKt;contentDeepEqualsInline;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepEqualsNullable;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepHashCodeInline;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepHashCodeNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepToStringInline;(Object[]);generated", - "kotlin.collections;ArraysKt;contentDeepToStringNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(char[],char[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(double[],double[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(float[],float[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(int[],int[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(long[],long[]);generated", - "kotlin.collections;ArraysKt;contentEquals;(short[],short[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(Object[],Object[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(char[],char[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(double[],double[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(float[],float[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(int[],int[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(long[],long[]);generated", - "kotlin.collections;ArraysKt;contentEqualsNullable;(short[],short[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(Object[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(byte[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(char[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(double[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(float[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(int[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(long[]);generated", - "kotlin.collections;ArraysKt;contentHashCode;(short[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(byte[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(char[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(double[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(float[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(int[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(long[]);generated", - "kotlin.collections;ArraysKt;contentHashCodeNullable;(short[]);generated", - "kotlin.collections;ArraysKt;contentToString;(Object[]);generated", - "kotlin.collections;ArraysKt;contentToString;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentToString;(byte[]);generated", - "kotlin.collections;ArraysKt;contentToString;(char[]);generated", - "kotlin.collections;ArraysKt;contentToString;(double[]);generated", - "kotlin.collections;ArraysKt;contentToString;(float[]);generated", - "kotlin.collections;ArraysKt;contentToString;(int[]);generated", - "kotlin.collections;ArraysKt;contentToString;(long[]);generated", - "kotlin.collections;ArraysKt;contentToString;(short[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(Object[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(boolean[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(byte[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(char[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(double[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(float[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(int[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(long[]);generated", - "kotlin.collections;ArraysKt;contentToStringNullable;(short[]);generated", - "kotlin.collections;ArraysKt;copyInto;(boolean[],boolean[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(double[],double[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(float[],float[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(int[],int[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(long[],long[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyInto;(short[],short[],int,int,int);generated", - "kotlin.collections;ArraysKt;copyOf;(boolean[]);generated", - "kotlin.collections;ArraysKt;copyOf;(boolean[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(double[]);generated", - "kotlin.collections;ArraysKt;copyOf;(double[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(float[]);generated", - "kotlin.collections;ArraysKt;copyOf;(float[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(int[]);generated", - "kotlin.collections;ArraysKt;copyOf;(int[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(long[]);generated", - "kotlin.collections;ArraysKt;copyOf;(long[],int);generated", - "kotlin.collections;ArraysKt;copyOf;(short[]);generated", - "kotlin.collections;ArraysKt;copyOf;(short[],int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(boolean[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(double[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(float[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(int[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(long[],int,int);generated", - "kotlin.collections;ArraysKt;copyOfRangeInline;(short[],int,int);generated", - "kotlin.collections;ArraysKt;count;(Object[]);generated", - "kotlin.collections;ArraysKt;count;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;count;(boolean[]);generated", - "kotlin.collections;ArraysKt;count;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;count;(byte[]);generated", - "kotlin.collections;ArraysKt;count;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;count;(char[]);generated", - "kotlin.collections;ArraysKt;count;(char[],Function1);generated", - "kotlin.collections;ArraysKt;count;(double[]);generated", - "kotlin.collections;ArraysKt;count;(double[],Function1);generated", - "kotlin.collections;ArraysKt;count;(float[]);generated", - "kotlin.collections;ArraysKt;count;(float[],Function1);generated", - "kotlin.collections;ArraysKt;count;(int[]);generated", - "kotlin.collections;ArraysKt;count;(int[],Function1);generated", - "kotlin.collections;ArraysKt;count;(long[]);generated", - "kotlin.collections;ArraysKt;count;(long[],Function1);generated", - "kotlin.collections;ArraysKt;count;(short[]);generated", - "kotlin.collections;ArraysKt;count;(short[],Function1);generated", - "kotlin.collections;ArraysKt;distinct;(Object[]);generated", - "kotlin.collections;ArraysKt;distinct;(boolean[]);generated", - "kotlin.collections;ArraysKt;distinct;(byte[]);generated", - "kotlin.collections;ArraysKt;distinct;(char[]);generated", - "kotlin.collections;ArraysKt;distinct;(double[]);generated", - "kotlin.collections;ArraysKt;distinct;(float[]);generated", - "kotlin.collections;ArraysKt;distinct;(int[]);generated", - "kotlin.collections;ArraysKt;distinct;(long[]);generated", - "kotlin.collections;ArraysKt;distinct;(short[]);generated", - "kotlin.collections;ArraysKt;distinctBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;distinctBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;drop;(boolean[],int);generated", - "kotlin.collections;ArraysKt;drop;(byte[],int);generated", - "kotlin.collections;ArraysKt;drop;(char[],int);generated", - "kotlin.collections;ArraysKt;drop;(double[],int);generated", - "kotlin.collections;ArraysKt;drop;(float[],int);generated", - "kotlin.collections;ArraysKt;drop;(int[],int);generated", - "kotlin.collections;ArraysKt;drop;(long[],int);generated", - "kotlin.collections;ArraysKt;drop;(short[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(boolean[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(byte[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(char[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(double[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(float[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(int[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(long[],int);generated", - "kotlin.collections;ArraysKt;dropLast;(short[],int);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;dropLastWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;dropWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;elementAt;(Object[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(boolean[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(byte[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(char[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(double[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(float[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(int[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(long[],int);generated", - "kotlin.collections;ArraysKt;elementAt;(short[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(Object[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(boolean[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(byte[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(char[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(double[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(float[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(int[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(long[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrElse;(short[],int,Function1);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(Object[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(boolean[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(byte[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(char[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(double[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(float[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(int[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(long[],int);generated", - "kotlin.collections;ArraysKt;elementAtOrNull;(short[],int);generated", - "kotlin.collections;ArraysKt;fill;(boolean[],boolean,int,int);generated", - "kotlin.collections;ArraysKt;fill;(byte[],byte,int,int);generated", - "kotlin.collections;ArraysKt;fill;(char[],char,int,int);generated", - "kotlin.collections;ArraysKt;fill;(double[],double,int,int);generated", - "kotlin.collections;ArraysKt;fill;(float[],float,int,int);generated", - "kotlin.collections;ArraysKt;fill;(int[],int,int,int);generated", - "kotlin.collections;ArraysKt;fill;(long[],long,int,int);generated", - "kotlin.collections;ArraysKt;fill;(short[],short,int,int);generated", - "kotlin.collections;ArraysKt;filter;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(char[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(double[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(float[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(int[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(long[],Function1);generated", - "kotlin.collections;ArraysKt;filter;(short[],Function1);generated", - "kotlin.collections;ArraysKt;filterIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;filterIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;filterIsInstance;(Object[]);generated", - "kotlin.collections;ArraysKt;filterIsInstance;(Object[],Class);generated", - "kotlin.collections;ArraysKt;filterNot;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(char[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(double[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(float[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(int[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(long[],Function1);generated", - "kotlin.collections;ArraysKt;filterNot;(short[],Function1);generated", - "kotlin.collections;ArraysKt;filterNotNull;(Object[]);generated", - "kotlin.collections;ArraysKt;find;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;find;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;find;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;find;(char[],Function1);generated", - "kotlin.collections;ArraysKt;find;(double[],Function1);generated", - "kotlin.collections;ArraysKt;find;(float[],Function1);generated", - "kotlin.collections;ArraysKt;find;(int[],Function1);generated", - "kotlin.collections;ArraysKt;find;(long[],Function1);generated", - "kotlin.collections;ArraysKt;find;(short[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(char[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(double[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(float[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(int[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(long[],Function1);generated", - "kotlin.collections;ArraysKt;findLast;(short[],Function1);generated", - "kotlin.collections;ArraysKt;first;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;first;(boolean[]);generated", - "kotlin.collections;ArraysKt;first;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;first;(byte[]);generated", - "kotlin.collections;ArraysKt;first;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;first;(char[]);generated", - "kotlin.collections;ArraysKt;first;(char[],Function1);generated", - "kotlin.collections;ArraysKt;first;(double[]);generated", - "kotlin.collections;ArraysKt;first;(double[],Function1);generated", - "kotlin.collections;ArraysKt;first;(float[]);generated", - "kotlin.collections;ArraysKt;first;(float[],Function1);generated", - "kotlin.collections;ArraysKt;first;(int[]);generated", - "kotlin.collections;ArraysKt;first;(int[],Function1);generated", - "kotlin.collections;ArraysKt;first;(long[]);generated", - "kotlin.collections;ArraysKt;first;(long[],Function1);generated", - "kotlin.collections;ArraysKt;first;(short[]);generated", - "kotlin.collections;ArraysKt;first;(short[],Function1);generated", - "kotlin.collections;ArraysKt;firstNotNullOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstNotNullOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;firstOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;firstOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(char[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(double[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(float[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(int[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(long[],Function1);generated", - "kotlin.collections;ArraysKt;flatMap;(short[],Function1);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(char[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(double[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(float[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(int[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(long[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedIterable;(short[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapIndexedSequence;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;flatMapSequence;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;flatten;(Object[][]);generated", - "kotlin.collections;ArraysKt;forEach;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(char[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(double[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(float[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(int[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(long[],Function1);generated", - "kotlin.collections;ArraysKt;forEach;(short[],Function1);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;forEachIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;getIndices;(Object[]);generated", - "kotlin.collections;ArraysKt;getIndices;(boolean[]);generated", - "kotlin.collections;ArraysKt;getIndices;(byte[]);generated", - "kotlin.collections;ArraysKt;getIndices;(char[]);generated", - "kotlin.collections;ArraysKt;getIndices;(double[]);generated", - "kotlin.collections;ArraysKt;getIndices;(float[]);generated", - "kotlin.collections;ArraysKt;getIndices;(int[]);generated", - "kotlin.collections;ArraysKt;getIndices;(long[]);generated", - "kotlin.collections;ArraysKt;getIndices;(short[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(Object[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(boolean[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(byte[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(char[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(double[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(float[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(int[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(long[]);generated", - "kotlin.collections;ArraysKt;getLastIndex;(short[]);generated", - "kotlin.collections;ArraysKt;getOrElse;(Object[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(boolean[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(byte[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(char[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(double[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(float[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(int[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(long[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrElse;(short[],int,Function1);generated", - "kotlin.collections;ArraysKt;getOrNull;(Object[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(boolean[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(byte[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(char[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(double[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(float[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(int[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(long[],int);generated", - "kotlin.collections;ArraysKt;getOrNull;(short[],int);generated", - "kotlin.collections;ArraysKt;groupBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(Object[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(boolean[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(byte[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(char[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(double[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(float[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(int[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(long[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;groupBy;(short[],Function1,Function1);generated", - "kotlin.collections;ArraysKt;groupingBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOf;(Object[],Object);generated", - "kotlin.collections;ArraysKt;indexOf;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;indexOf;(byte[],byte);generated", - "kotlin.collections;ArraysKt;indexOf;(char[],char);generated", - "kotlin.collections;ArraysKt;indexOf;(double[],double);generated", - "kotlin.collections;ArraysKt;indexOf;(float[],float);generated", - "kotlin.collections;ArraysKt;indexOf;(int[],int);generated", - "kotlin.collections;ArraysKt;indexOf;(long[],long);generated", - "kotlin.collections;ArraysKt;indexOf;(short[],short);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(char[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(double[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(float[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(int[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(long[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfFirst;(short[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(char[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(double[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(float[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(int[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(long[],Function1);generated", - "kotlin.collections;ArraysKt;indexOfLast;(short[],Function1);generated", - "kotlin.collections;ArraysKt;intersect;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;intersect;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;isEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(boolean[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(byte[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(char[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(double[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(float[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(int[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(long[]);generated", - "kotlin.collections;ArraysKt;isEmpty;(short[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(boolean[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(byte[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(char[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(double[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(float[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(int[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(long[]);generated", - "kotlin.collections;ArraysKt;isNotEmpty;(short[]);generated", - "kotlin.collections;ArraysKt;isNullOrEmpty;(Object[]);generated", - "kotlin.collections;ArraysKt;last;(boolean[]);generated", - "kotlin.collections;ArraysKt;last;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;last;(byte[]);generated", - "kotlin.collections;ArraysKt;last;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;last;(char[]);generated", - "kotlin.collections;ArraysKt;last;(char[],Function1);generated", - "kotlin.collections;ArraysKt;last;(double[]);generated", - "kotlin.collections;ArraysKt;last;(double[],Function1);generated", - "kotlin.collections;ArraysKt;last;(float[]);generated", - "kotlin.collections;ArraysKt;last;(float[],Function1);generated", - "kotlin.collections;ArraysKt;last;(int[]);generated", - "kotlin.collections;ArraysKt;last;(int[],Function1);generated", - "kotlin.collections;ArraysKt;last;(long[]);generated", - "kotlin.collections;ArraysKt;last;(long[],Function1);generated", - "kotlin.collections;ArraysKt;last;(short[]);generated", - "kotlin.collections;ArraysKt;last;(short[],Function1);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(Object[],Object);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(byte[],byte);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(char[],char);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(double[],double);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(float[],float);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(int[],int);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(long[],long);generated", - "kotlin.collections;ArraysKt;lastIndexOf;(short[],short);generated", - "kotlin.collections;ArraysKt;lastOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;lastOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;lastOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;map;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;map;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;map;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;map;(char[],Function1);generated", - "kotlin.collections;ArraysKt;map;(double[],Function1);generated", - "kotlin.collections;ArraysKt;map;(float[],Function1);generated", - "kotlin.collections;ArraysKt;map;(int[],Function1);generated", - "kotlin.collections;ArraysKt;map;(long[],Function1);generated", - "kotlin.collections;ArraysKt;map;(short[],Function1);generated", - "kotlin.collections;ArraysKt;mapIndexed;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(char[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;mapIndexedNotNull;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;mapNotNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;max;(Double[]);generated", - "kotlin.collections;ArraysKt;max;(Float[]);generated", - "kotlin.collections;ArraysKt;max;(byte[]);generated", - "kotlin.collections;ArraysKt;max;(char[]);generated", - "kotlin.collections;ArraysKt;max;(double[]);generated", - "kotlin.collections;ArraysKt;max;(float[]);generated", - "kotlin.collections;ArraysKt;max;(int[]);generated", - "kotlin.collections;ArraysKt;max;(long[]);generated", - "kotlin.collections;ArraysKt;max;(short[]);generated", - "kotlin.collections;ArraysKt;maxBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxByOrThrow;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxOf;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWith;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOfWithOrNull;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;maxOrNull;(Double[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(Float[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;maxOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(Double[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(Float[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(byte[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(char[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(double[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(float[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(int[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(long[]);generated", - "kotlin.collections;ArraysKt;maxOrThrow;(short[]);generated", - "kotlin.collections;ArraysKt;maxWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrNull;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;maxWithOrThrow;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;min;(Double[]);generated", - "kotlin.collections;ArraysKt;min;(Float[]);generated", - "kotlin.collections;ArraysKt;min;(byte[]);generated", - "kotlin.collections;ArraysKt;min;(char[]);generated", - "kotlin.collections;ArraysKt;min;(double[]);generated", - "kotlin.collections;ArraysKt;min;(float[]);generated", - "kotlin.collections;ArraysKt;min;(int[]);generated", - "kotlin.collections;ArraysKt;min;(long[]);generated", - "kotlin.collections;ArraysKt;min;(short[]);generated", - "kotlin.collections;ArraysKt;minBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minByOrThrow;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minOf;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;minOfOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWith;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(boolean[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(byte[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(char[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(double[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(float[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(int[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(long[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOfWithOrNull;(short[],Comparator,Function1);generated", - "kotlin.collections;ArraysKt;minOrNull;(Double[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(Float[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;minOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(Double[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(Float[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(byte[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(char[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(double[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(float[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(int[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(long[]);generated", - "kotlin.collections;ArraysKt;minOrThrow;(short[]);generated", - "kotlin.collections;ArraysKt;minWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrNull;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;minWithOrThrow;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;none;(Object[]);generated", - "kotlin.collections;ArraysKt;none;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;none;(boolean[]);generated", - "kotlin.collections;ArraysKt;none;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;none;(byte[]);generated", - "kotlin.collections;ArraysKt;none;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;none;(char[]);generated", - "kotlin.collections;ArraysKt;none;(char[],Function1);generated", - "kotlin.collections;ArraysKt;none;(double[]);generated", - "kotlin.collections;ArraysKt;none;(double[],Function1);generated", - "kotlin.collections;ArraysKt;none;(float[]);generated", - "kotlin.collections;ArraysKt;none;(float[],Function1);generated", - "kotlin.collections;ArraysKt;none;(int[]);generated", - "kotlin.collections;ArraysKt;none;(int[],Function1);generated", - "kotlin.collections;ArraysKt;none;(long[]);generated", - "kotlin.collections;ArraysKt;none;(long[],Function1);generated", - "kotlin.collections;ArraysKt;none;(short[]);generated", - "kotlin.collections;ArraysKt;none;(short[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(double[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(float[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(int[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(long[],Function1);generated", - "kotlin.collections;ArraysKt;onEach;(short[],Function1);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(double[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(float[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(int[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(long[],Function2);generated", - "kotlin.collections;ArraysKt;onEachIndexed;(short[],Function2);generated", - "kotlin.collections;ArraysKt;partition;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(char[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(double[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(float[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(int[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(long[],Function1);generated", - "kotlin.collections;ArraysKt;partition;(short[],Function1);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],boolean);generated", - "kotlin.collections;ArraysKt;plus;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;plus;(double[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(double[],double);generated", - "kotlin.collections;ArraysKt;plus;(double[],double[]);generated", - "kotlin.collections;ArraysKt;plus;(float[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(float[],float);generated", - "kotlin.collections;ArraysKt;plus;(float[],float[]);generated", - "kotlin.collections;ArraysKt;plus;(int[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(int[],int);generated", - "kotlin.collections;ArraysKt;plus;(int[],int[]);generated", - "kotlin.collections;ArraysKt;plus;(long[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(long[],long);generated", - "kotlin.collections;ArraysKt;plus;(long[],long[]);generated", - "kotlin.collections;ArraysKt;plus;(short[],Collection);generated", - "kotlin.collections;ArraysKt;plus;(short[],short);generated", - "kotlin.collections;ArraysKt;plus;(short[],short[]);generated", - "kotlin.collections;ArraysKt;random;(Object[]);generated", - "kotlin.collections;ArraysKt;random;(Object[],Random);generated", - "kotlin.collections;ArraysKt;random;(boolean[]);generated", - "kotlin.collections;ArraysKt;random;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;random;(byte[]);generated", - "kotlin.collections;ArraysKt;random;(byte[],Random);generated", - "kotlin.collections;ArraysKt;random;(char[]);generated", - "kotlin.collections;ArraysKt;random;(char[],Random);generated", - "kotlin.collections;ArraysKt;random;(double[]);generated", - "kotlin.collections;ArraysKt;random;(double[],Random);generated", - "kotlin.collections;ArraysKt;random;(float[]);generated", - "kotlin.collections;ArraysKt;random;(float[],Random);generated", - "kotlin.collections;ArraysKt;random;(int[]);generated", - "kotlin.collections;ArraysKt;random;(int[],Random);generated", - "kotlin.collections;ArraysKt;random;(long[]);generated", - "kotlin.collections;ArraysKt;random;(long[],Random);generated", - "kotlin.collections;ArraysKt;random;(short[]);generated", - "kotlin.collections;ArraysKt;random;(short[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(Object[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(Object[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(byte[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(char[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(double[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(float[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(int[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(long[],Random);generated", - "kotlin.collections;ArraysKt;randomOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;randomOrNull;(short[],Random);generated", - "kotlin.collections;ArraysKt;reduce;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduce;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceIndexedOrNull;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceOrNull;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRight;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(char[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(double[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(float[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(int[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(long[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightIndexedOrNull;(short[],Function3);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(char[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(double[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(float[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(int[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(long[],Function2);generated", - "kotlin.collections;ArraysKt;reduceRightOrNull;(short[],Function2);generated", - "kotlin.collections;ArraysKt;reverse;(Object[]);generated", - "kotlin.collections;ArraysKt;reverse;(Object[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(boolean[]);generated", - "kotlin.collections;ArraysKt;reverse;(boolean[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(byte[]);generated", - "kotlin.collections;ArraysKt;reverse;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(char[]);generated", - "kotlin.collections;ArraysKt;reverse;(char[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(double[]);generated", - "kotlin.collections;ArraysKt;reverse;(double[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(float[]);generated", - "kotlin.collections;ArraysKt;reverse;(float[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(int[]);generated", - "kotlin.collections;ArraysKt;reverse;(int[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(long[]);generated", - "kotlin.collections;ArraysKt;reverse;(long[],int,int);generated", - "kotlin.collections;ArraysKt;reverse;(short[]);generated", - "kotlin.collections;ArraysKt;reverse;(short[],int,int);generated", - "kotlin.collections;ArraysKt;reversed;(boolean[]);generated", - "kotlin.collections;ArraysKt;reversed;(byte[]);generated", - "kotlin.collections;ArraysKt;reversed;(char[]);generated", - "kotlin.collections;ArraysKt;reversed;(double[]);generated", - "kotlin.collections;ArraysKt;reversed;(float[]);generated", - "kotlin.collections;ArraysKt;reversed;(int[]);generated", - "kotlin.collections;ArraysKt;reversed;(long[]);generated", - "kotlin.collections;ArraysKt;reversed;(short[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(boolean[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(double[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(float[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(int[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(long[]);generated", - "kotlin.collections;ArraysKt;reversedArray;(short[]);generated", - "kotlin.collections;ArraysKt;runningReduce;(Object[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(boolean[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(byte[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(char[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(double[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(float[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(int[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(long[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduce;(short[],Function2);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(Object[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(boolean[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(byte[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(char[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(double[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(float[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(int[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(long[],Function3);generated", - "kotlin.collections;ArraysKt;runningReduceIndexed;(short[],Function3);generated", - "kotlin.collections;ArraysKt;shuffle;(Object[]);generated", - "kotlin.collections;ArraysKt;shuffle;(Object[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(boolean[]);generated", - "kotlin.collections;ArraysKt;shuffle;(boolean[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(byte[]);generated", - "kotlin.collections;ArraysKt;shuffle;(byte[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(char[]);generated", - "kotlin.collections;ArraysKt;shuffle;(char[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(double[]);generated", - "kotlin.collections;ArraysKt;shuffle;(double[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(float[]);generated", - "kotlin.collections;ArraysKt;shuffle;(float[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(int[]);generated", - "kotlin.collections;ArraysKt;shuffle;(int[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(long[]);generated", - "kotlin.collections;ArraysKt;shuffle;(long[],Random);generated", - "kotlin.collections;ArraysKt;shuffle;(short[]);generated", - "kotlin.collections;ArraysKt;shuffle;(short[],Random);generated", - "kotlin.collections;ArraysKt;single;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;single;(boolean[]);generated", - "kotlin.collections;ArraysKt;single;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;single;(byte[]);generated", - "kotlin.collections;ArraysKt;single;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;single;(char[]);generated", - "kotlin.collections;ArraysKt;single;(char[],Function1);generated", - "kotlin.collections;ArraysKt;single;(double[]);generated", - "kotlin.collections;ArraysKt;single;(double[],Function1);generated", - "kotlin.collections;ArraysKt;single;(float[]);generated", - "kotlin.collections;ArraysKt;single;(float[],Function1);generated", - "kotlin.collections;ArraysKt;single;(int[]);generated", - "kotlin.collections;ArraysKt;single;(int[],Function1);generated", - "kotlin.collections;ArraysKt;single;(long[]);generated", - "kotlin.collections;ArraysKt;single;(long[],Function1);generated", - "kotlin.collections;ArraysKt;single;(short[]);generated", - "kotlin.collections;ArraysKt;single;(short[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(boolean[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(byte[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(char[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(char[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(double[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(double[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(float[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(float[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(int[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(int[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(long[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(long[],Function1);generated", - "kotlin.collections;ArraysKt;singleOrNull;(short[]);generated", - "kotlin.collections;ArraysKt;singleOrNull;(short[],Function1);generated", - "kotlin.collections;ArraysKt;slice;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(boolean[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(byte[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(char[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(double[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(float[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(int[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(long[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;slice;(short[],IntRange);generated", - "kotlin.collections;ArraysKt;slice;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;sliceArray;(boolean[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(boolean[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(byte[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(char[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(double[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(double[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(float[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(float[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(int[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(int[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(long[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(long[],IntRange);generated", - "kotlin.collections;ArraysKt;sliceArray;(short[],Collection);generated", - "kotlin.collections;ArraysKt;sliceArray;(short[],IntRange);generated", - "kotlin.collections;ArraysKt;sort;(Comparable[]);generated", - "kotlin.collections;ArraysKt;sort;(Comparable[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(Object[]);generated", - "kotlin.collections;ArraysKt;sort;(Object[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(byte[]);generated", - "kotlin.collections;ArraysKt;sort;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(char[]);generated", - "kotlin.collections;ArraysKt;sort;(char[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(double[]);generated", - "kotlin.collections;ArraysKt;sort;(double[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(float[]);generated", - "kotlin.collections;ArraysKt;sort;(float[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(int[]);generated", - "kotlin.collections;ArraysKt;sort;(int[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(long[]);generated", - "kotlin.collections;ArraysKt;sort;(long[],int,int);generated", - "kotlin.collections;ArraysKt;sort;(short[]);generated", - "kotlin.collections;ArraysKt;sort;(short[],int,int);generated", - "kotlin.collections;ArraysKt;sortBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sortByDescending;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sortDescending;(Comparable[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(Comparable[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(byte[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(byte[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(char[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(char[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(double[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(float[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(int[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(long[],int,int);generated", - "kotlin.collections;ArraysKt;sortDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortDescending;(short[],int,int);generated", - "kotlin.collections;ArraysKt;sortWith;(Object[],Comparator);generated", - "kotlin.collections;ArraysKt;sortWith;(Object[],Comparator,int,int);generated", - "kotlin.collections;ArraysKt;sorted;(byte[]);generated", - "kotlin.collections;ArraysKt;sorted;(char[]);generated", - "kotlin.collections;ArraysKt;sorted;(double[]);generated", - "kotlin.collections;ArraysKt;sorted;(float[]);generated", - "kotlin.collections;ArraysKt;sorted;(int[]);generated", - "kotlin.collections;ArraysKt;sorted;(long[]);generated", - "kotlin.collections;ArraysKt;sorted;(short[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(double[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(float[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(int[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(long[]);generated", - "kotlin.collections;ArraysKt;sortedArray;(short[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortedArrayDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortedBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sortedBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sortedByDescending;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sortedDescending;(byte[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(char[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(double[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(float[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(int[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(long[]);generated", - "kotlin.collections;ArraysKt;sortedDescending;(short[]);generated", - "kotlin.collections;ArraysKt;sortedWith;(boolean[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(byte[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(char[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(double[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(float[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(int[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(long[],Comparator);generated", - "kotlin.collections;ArraysKt;sortedWith;(short[],Comparator);generated", - "kotlin.collections;ArraysKt;subtract;(Object[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;subtract;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;sum;(byte[]);generated", - "kotlin.collections;ArraysKt;sum;(double[]);generated", - "kotlin.collections;ArraysKt;sum;(float[]);generated", - "kotlin.collections;ArraysKt;sum;(int[]);generated", - "kotlin.collections;ArraysKt;sum;(long[]);generated", - "kotlin.collections;ArraysKt;sum;(short[]);generated", - "kotlin.collections;ArraysKt;sumBy;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumBy;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumByDouble;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigDecimal;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfBigInteger;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfByte;(Byte[]);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(Double[]);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfDouble;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfFloat;(Float[]);generated", - "kotlin.collections;ArraysKt;sumOfInt;(Integer[]);generated", - "kotlin.collections;ArraysKt;sumOfInt;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfInt;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(Long[]);generated", - "kotlin.collections;ArraysKt;sumOfLong;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfLong;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfShort;(Short[]);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfUInt;(short[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(char[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(double[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(float[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(int[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(long[],Function1);generated", - "kotlin.collections;ArraysKt;sumOfULong;(short[],Function1);generated", - "kotlin.collections;ArraysKt;take;(boolean[],int);generated", - "kotlin.collections;ArraysKt;take;(byte[],int);generated", - "kotlin.collections;ArraysKt;take;(char[],int);generated", - "kotlin.collections;ArraysKt;take;(double[],int);generated", - "kotlin.collections;ArraysKt;take;(float[],int);generated", - "kotlin.collections;ArraysKt;take;(int[],int);generated", - "kotlin.collections;ArraysKt;take;(long[],int);generated", - "kotlin.collections;ArraysKt;take;(short[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(boolean[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(byte[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(char[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(double[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(float[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(int[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(long[],int);generated", - "kotlin.collections;ArraysKt;takeLast;(short[],int);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;takeLastWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(Object[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(boolean[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(byte[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(char[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(double[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(float[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(int[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(long[],Function1);generated", - "kotlin.collections;ArraysKt;takeWhile;(short[],Function1);generated", - "kotlin.collections;ArraysKt;toBooleanArray;(Boolean[]);generated", - "kotlin.collections;ArraysKt;toByteArray;(Byte[]);generated", - "kotlin.collections;ArraysKt;toCharArray;(Character[]);generated", - "kotlin.collections;ArraysKt;toDoubleArray;(Double[]);generated", - "kotlin.collections;ArraysKt;toFloatArray;(Float[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(Object[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(char[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(double[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(float[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(int[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(long[]);generated", - "kotlin.collections;ArraysKt;toHashSet;(short[]);generated", - "kotlin.collections;ArraysKt;toIntArray;(Integer[]);generated", - "kotlin.collections;ArraysKt;toList;(boolean[]);generated", - "kotlin.collections;ArraysKt;toList;(byte[]);generated", - "kotlin.collections;ArraysKt;toList;(char[]);generated", - "kotlin.collections;ArraysKt;toList;(double[]);generated", - "kotlin.collections;ArraysKt;toList;(float[]);generated", - "kotlin.collections;ArraysKt;toList;(int[]);generated", - "kotlin.collections;ArraysKt;toList;(long[]);generated", - "kotlin.collections;ArraysKt;toList;(short[]);generated", - "kotlin.collections;ArraysKt;toLongArray;(Long[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(boolean[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(byte[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(char[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(double[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(float[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(int[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(long[]);generated", - "kotlin.collections;ArraysKt;toMutableList;(short[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(Object[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(char[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(double[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(float[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(int[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(long[]);generated", - "kotlin.collections;ArraysKt;toMutableSet;(short[]);generated", - "kotlin.collections;ArraysKt;toSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toSet;(char[]);generated", - "kotlin.collections;ArraysKt;toSet;(double[]);generated", - "kotlin.collections;ArraysKt;toSet;(float[]);generated", - "kotlin.collections;ArraysKt;toSet;(int[]);generated", - "kotlin.collections;ArraysKt;toSet;(long[]);generated", - "kotlin.collections;ArraysKt;toSet;(short[]);generated", - "kotlin.collections;ArraysKt;toShortArray;(Short[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(Comparable[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(Object[],Comparator);generated", - "kotlin.collections;ArraysKt;toSortedSet;(boolean[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(byte[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(char[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(double[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(float[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(int[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(long[]);generated", - "kotlin.collections;ArraysKt;toSortedSet;(short[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(boolean[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(byte[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(char[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(double[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(float[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(int[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(long[]);generated", - "kotlin.collections;ArraysKt;toTypedArray;(short[]);generated", - "kotlin.collections;ArraysKt;union;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;union;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;unzip;(Pair[]);generated", - "kotlin.collections;ArraysKt;withIndex;(Object[]);generated", - "kotlin.collections;ArraysKt;withIndex;(boolean[]);generated", - "kotlin.collections;ArraysKt;withIndex;(byte[]);generated", - "kotlin.collections;ArraysKt;withIndex;(char[]);generated", - "kotlin.collections;ArraysKt;withIndex;(double[]);generated", - "kotlin.collections;ArraysKt;withIndex;(float[]);generated", - "kotlin.collections;ArraysKt;withIndex;(int[]);generated", - "kotlin.collections;ArraysKt;withIndex;(long[]);generated", - "kotlin.collections;ArraysKt;withIndex;(short[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],boolean[]);generated", - "kotlin.collections;ArraysKt;zip;(boolean[],boolean[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(byte[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(byte[],byte[]);generated", - "kotlin.collections;ArraysKt;zip;(byte[],byte[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(char[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(char[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(char[],char[]);generated", - "kotlin.collections;ArraysKt;zip;(char[],char[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(double[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(double[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(double[],double[]);generated", - "kotlin.collections;ArraysKt;zip;(double[],double[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(float[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(float[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(float[],float[]);generated", - "kotlin.collections;ArraysKt;zip;(float[],float[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(int[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(int[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(int[],int[]);generated", - "kotlin.collections;ArraysKt;zip;(int[],int[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(long[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(long[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(long[],long[]);generated", - "kotlin.collections;ArraysKt;zip;(long[],long[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],Iterable);generated", - "kotlin.collections;ArraysKt;zip;(short[],Iterable,Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],Object[]);generated", - "kotlin.collections;ArraysKt;zip;(short[],Object[],Function2);generated", - "kotlin.collections;ArraysKt;zip;(short[],short[]);generated", - "kotlin.collections;ArraysKt;zip;(short[],short[],Function2);generated", - "kotlin.collections;BooleanIterator;BooleanIterator;();generated", - "kotlin.collections;BooleanIterator;nextBoolean;();generated", - "kotlin.collections;ByteIterator;ByteIterator;();generated", - "kotlin.collections;ByteIterator;nextByte;();generated", - "kotlin.collections;CharIterator;CharIterator;();generated", - "kotlin.collections;CharIterator;nextChar;();generated", - "kotlin.collections;CollectionsHKt;eachCount;(Grouping);generated", - "kotlin.collections;CollectionsHKt;fill;(List,Object);generated", - "kotlin.collections;CollectionsHKt;orEmpty;(Object[]);generated", - "kotlin.collections;CollectionsHKt;shuffle;(List);generated", - "kotlin.collections;CollectionsHKt;shuffled;(Iterable);generated", - "kotlin.collections;CollectionsHKt;sort;(List);generated", - "kotlin.collections;CollectionsHKt;sortWith;(List,Comparator);generated", - "kotlin.collections;CollectionsHKt;toTypedArray;(Collection);generated", - "kotlin.collections;CollectionsKt;Iterable;(Function0);generated", - "kotlin.collections;CollectionsKt;List;(int,Function1);generated", - "kotlin.collections;CollectionsKt;MutableList;(int,Function1);generated", - "kotlin.collections;CollectionsKt;all;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;any;(Iterable);generated", - "kotlin.collections;CollectionsKt;any;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;arrayListOf;();generated", - "kotlin.collections;CollectionsKt;asSequence;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfByte;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfDouble;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfFloat;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfInt;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfLong;(Iterable);generated", - "kotlin.collections;CollectionsKt;averageOfShort;(Iterable);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,Comparable,int,int);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,Object,Comparator,int,int);generated", - "kotlin.collections;CollectionsKt;binarySearch;(List,int,int,Function1);generated", - "kotlin.collections;CollectionsKt;binarySearchBy;(List,Comparable,int,int,Function1);generated", - "kotlin.collections;CollectionsKt;buildList;(Function1);generated", - "kotlin.collections;CollectionsKt;buildList;(int,Function1);generated", - "kotlin.collections;CollectionsKt;chunked;(Iterable,int);generated", - "kotlin.collections;CollectionsKt;chunked;(Iterable,int,Function1);generated", - "kotlin.collections;CollectionsKt;contains;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;containsAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;count;(Collection);generated", - "kotlin.collections;CollectionsKt;count;(Iterable);generated", - "kotlin.collections;CollectionsKt;count;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;emptyList;();generated", - "kotlin.collections;CollectionsKt;filterIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMap;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;flatMapIndexedIterable;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMapIndexedSequence;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;flatMapSequence;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;forEach;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;forEach;(Iterator,Function1);generated", - "kotlin.collections;CollectionsKt;forEachIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;getIndices;(Collection);generated", - "kotlin.collections;CollectionsKt;getLastIndex;(List);generated", - "kotlin.collections;CollectionsKt;groupBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;groupBy;(Iterable,Function1,Function1);generated", - "kotlin.collections;CollectionsKt;groupingBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOf;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;indexOf;(List,Object);generated", - "kotlin.collections;CollectionsKt;indexOfFirst;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfFirst;(List,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfLast;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;indexOfLast;(List,Function1);generated", - "kotlin.collections;CollectionsKt;isNotEmpty;(Collection);generated", - "kotlin.collections;CollectionsKt;isNullOrEmpty;(Collection);generated", - "kotlin.collections;CollectionsKt;iterator;(Enumeration);generated", - "kotlin.collections;CollectionsKt;lastIndexOf;(Iterable,Object);generated", - "kotlin.collections;CollectionsKt;lastIndexOf;(List,Object);generated", - "kotlin.collections;CollectionsKt;listOf;();generated", - "kotlin.collections;CollectionsKt;listOfNotNull;(Object[]);generated", - "kotlin.collections;CollectionsKt;mapIndexed;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;mapIndexedNotNull;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;mapNotNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;max;(Iterable);generated", - "kotlin.collections;CollectionsKt;maxOf;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;maxOfOrNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;maxOrNull;(Iterable);generated", - "kotlin.collections;CollectionsKt;maxOrThrow;(Iterable);generated", - "kotlin.collections;CollectionsKt;min;(Iterable);generated", - "kotlin.collections;CollectionsKt;minOf;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;minOfOrNull;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;minOrNull;(Iterable);generated", - "kotlin.collections;CollectionsKt;minOrThrow;(Iterable);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Object);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;minusAssign;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;mutableListOf;();generated", - "kotlin.collections;CollectionsKt;none;(Iterable);generated", - "kotlin.collections;CollectionsKt;none;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;remove;(Collection,Object);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;removeAll;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;removeAll;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;removeAll;(List,Function1);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Collection);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Iterable);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Object[]);generated", - "kotlin.collections;CollectionsKt;retainAll;(Collection,Sequence);generated", - "kotlin.collections;CollectionsKt;retainAll;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;retainAll;(List,Function1);generated", - "kotlin.collections;CollectionsKt;reverse;(List);generated", - "kotlin.collections;CollectionsKt;runningReduce;(Iterable,Function2);generated", - "kotlin.collections;CollectionsKt;runningReduceIndexed;(Iterable,Function3);generated", - "kotlin.collections;CollectionsKt;shuffle;(List);generated", - "kotlin.collections;CollectionsKt;shuffle;(List,Random);generated", - "kotlin.collections;CollectionsKt;sort;(List);generated", - "kotlin.collections;CollectionsKt;sort;(List,Comparator);generated", - "kotlin.collections;CollectionsKt;sort;(List,Function2);generated", - "kotlin.collections;CollectionsKt;sortBy;(List,Function1);generated", - "kotlin.collections;CollectionsKt;sortByDescending;(List,Function1);generated", - "kotlin.collections;CollectionsKt;sortDescending;(List);generated", - "kotlin.collections;CollectionsKt;sortWith;(List,Comparator);generated", - "kotlin.collections;CollectionsKt;sumBy;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumByDouble;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfBigDecimal;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfBigInteger;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfByte;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfDouble;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfDouble;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfFloat;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfInt;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfInt;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfLong;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfLong;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfShort;(Iterable);generated", - "kotlin.collections;CollectionsKt;sumOfUInt;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;sumOfULong;(Iterable,Function1);generated", - "kotlin.collections;CollectionsKt;toBooleanArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toByteArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toCharArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toDoubleArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toFloatArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toIntArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toLongArray;(Collection);generated", - "kotlin.collections;CollectionsKt;toShortArray;(Collection);generated", - "kotlin.collections;CollectionsKt;windowed;(Iterable,int,int,boolean);generated", - "kotlin.collections;CollectionsKt;windowed;(Iterable,int,int,boolean,Function1);generated", - "kotlin.collections;CollectionsKt;withIndex;(Iterable);generated", - "kotlin.collections;DoubleIterator;DoubleIterator;();generated", - "kotlin.collections;DoubleIterator;nextDouble;();generated", - "kotlin.collections;FloatIterator;FloatIterator;();generated", - "kotlin.collections;FloatIterator;nextFloat;();generated", - "kotlin.collections;Grouping;keyOf;(Object);generated", - "kotlin.collections;Grouping;sourceIterator;();generated", - "kotlin.collections;GroupingKt;aggregate;(Grouping,Function4);generated", - "kotlin.collections;GroupingKt;eachCount;(Grouping);generated", - "kotlin.collections;GroupingKt;fold;(Grouping,Function2,Function3);generated", - "kotlin.collections;GroupingKt;fold;(Grouping,Object,Function2);generated", - "kotlin.collections;GroupingKt;reduce;(Grouping,Function3);generated", - "kotlin.collections;HashMap;HashMap;();generated", - "kotlin.collections;HashMap;HashMap;(Map);generated", - "kotlin.collections;HashMap;HashMap;(int);generated", - "kotlin.collections;HashMap;HashMap;(int,float);generated", - "kotlin.collections;HashSet;HashSet;();generated", - "kotlin.collections;HashSet;HashSet;(Collection);generated", - "kotlin.collections;HashSet;HashSet;(int);generated", - "kotlin.collections;HashSet;HashSet;(int,float);generated", - "kotlin.collections;IndexedValue;component1;();generated", - "kotlin.collections;IndexedValue;equals;(Object);generated", - "kotlin.collections;IndexedValue;getIndex;();generated", - "kotlin.collections;IndexedValue;hashCode;();generated", - "kotlin.collections;IntIterator;IntIterator;();generated", - "kotlin.collections;IntIterator;nextInt;();generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;();generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(Map);generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(int);generated", - "kotlin.collections;LinkedHashMap;LinkedHashMap;(int,float);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;();generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(Collection);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(int);generated", - "kotlin.collections;LinkedHashSet;LinkedHashSet;(int,float);generated", - "kotlin.collections;LongIterator;LongIterator;();generated", - "kotlin.collections;LongIterator;nextLong;();generated", - "kotlin.collections;MapsKt;all;(Map,Function1);generated", - "kotlin.collections;MapsKt;any;(Map);generated", - "kotlin.collections;MapsKt;any;(Map,Function1);generated", - "kotlin.collections;MapsKt;asSequence;(Map);generated", - "kotlin.collections;MapsKt;buildMap;(Function1);generated", - "kotlin.collections;MapsKt;buildMap;(int,Function1);generated", - "kotlin.collections;MapsKt;contains;(Map,Object);generated", - "kotlin.collections;MapsKt;containsKey;(Map,Object);generated", - "kotlin.collections;MapsKt;containsValue;(Map,Object);generated", - "kotlin.collections;MapsKt;count;(Map);generated", - "kotlin.collections;MapsKt;count;(Map,Function1);generated", - "kotlin.collections;MapsKt;emptyMap;();generated", - "kotlin.collections;MapsKt;flatMap;(Map,Function1);generated", - "kotlin.collections;MapsKt;flatMapSequence;(Map,Function1);generated", - "kotlin.collections;MapsKt;forEach;(Map,Function1);generated", - "kotlin.collections;MapsKt;hashMapOf;();generated", - "kotlin.collections;MapsKt;hashMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;isNotEmpty;(Map);generated", - "kotlin.collections;MapsKt;isNullOrEmpty;(Map);generated", - "kotlin.collections;MapsKt;linkedMapOf;();generated", - "kotlin.collections;MapsKt;linkedMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;mapNotNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;mapOf;();generated", - "kotlin.collections;MapsKt;mapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;maxOf;(Map,Function1);generated", - "kotlin.collections;MapsKt;maxOfOrNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;minOf;(Map,Function1);generated", - "kotlin.collections;MapsKt;minOfOrNull;(Map,Function1);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Iterable);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Object);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Object[]);generated", - "kotlin.collections;MapsKt;minusAssign;(Map,Sequence);generated", - "kotlin.collections;MapsKt;mutableMapOf;();generated", - "kotlin.collections;MapsKt;mutableMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;none;(Map);generated", - "kotlin.collections;MapsKt;none;(Map,Function1);generated", - "kotlin.collections;MapsKt;plusAssign;(Map,Pair[]);generated", - "kotlin.collections;MapsKt;putAll;(Map,Pair[]);generated", - "kotlin.collections;MapsKt;sortedMapOf;(Comparator,Pair[]);generated", - "kotlin.collections;MapsKt;sortedMapOf;(Pair[]);generated", - "kotlin.collections;MapsKt;toMap;(Sequence);generated", - "kotlin.collections;MapsKt;toProperties;(Map);generated", - "kotlin.collections;MapsKt;toSortedMap;(Map,Comparator);generated", - "kotlin.collections;SetsKt;buildSet;(Function1);generated", - "kotlin.collections;SetsKt;buildSet;(int,Function1);generated", - "kotlin.collections;SetsKt;emptySet;();generated", - "kotlin.collections;SetsKt;hashSetOf;();generated", - "kotlin.collections;SetsKt;hashSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;linkedSetOf;();generated", - "kotlin.collections;SetsKt;linkedSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;mutableSetOf;();generated", - "kotlin.collections;SetsKt;mutableSetOf;(Object[]);generated", - "kotlin.collections;SetsKt;setOf;();generated", - "kotlin.collections;SetsKt;setOfNotNull;(Object[]);generated", - "kotlin.collections;SetsKt;sortedSetOf;(Comparator,Object[]);generated", - "kotlin.collections;SetsKt;sortedSetOf;(Object[]);generated", - "kotlin.collections;ShortIterator;ShortIterator;();generated", - "kotlin.collections;ShortIterator;nextShort;();generated", - "kotlin.collections;UArraysKt;all;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;all;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UByteArray);generated", - "kotlin.collections;UArraysKt;any;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UIntArray);generated", - "kotlin.collections;UArraysKt;any;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(ULongArray);generated", - "kotlin.collections;UArraysKt;any;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;any;(UShortArray);generated", - "kotlin.collections;UArraysKt;any;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;asIntArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;asList;(UByteArray);generated", - "kotlin.collections;UArraysKt;asList;(UIntArray);generated", - "kotlin.collections;UArraysKt;asList;(ULongArray);generated", - "kotlin.collections;UArraysKt;asList;(UShortArray);generated", - "kotlin.collections;UArraysKt;asLongArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;asShortArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;asUIntArray;(int[]);generated", - "kotlin.collections;UArraysKt;asULongArray;(long[]);generated", - "kotlin.collections;UArraysKt;asUShortArray;(short[]);generated", - "kotlin.collections;UArraysKt;associateWith;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;associateWith;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;binarySearch;(UByteArray,byte,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(UIntArray,int,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(ULongArray,long,int,int);generated", - "kotlin.collections;UArraysKt;binarySearch;(UShortArray,short,int,int);generated", - "kotlin.collections;UArraysKt;component1;(UByteArray);generated", - "kotlin.collections;UArraysKt;component1;(UIntArray);generated", - "kotlin.collections;UArraysKt;component1;(ULongArray);generated", - "kotlin.collections;UArraysKt;component1;(UShortArray);generated", - "kotlin.collections;UArraysKt;component2;(UByteArray);generated", - "kotlin.collections;UArraysKt;component2;(UIntArray);generated", - "kotlin.collections;UArraysKt;component2;(ULongArray);generated", - "kotlin.collections;UArraysKt;component2;(UShortArray);generated", - "kotlin.collections;UArraysKt;component3;(UByteArray);generated", - "kotlin.collections;UArraysKt;component3;(UIntArray);generated", - "kotlin.collections;UArraysKt;component3;(ULongArray);generated", - "kotlin.collections;UArraysKt;component3;(UShortArray);generated", - "kotlin.collections;UArraysKt;component4;(UByteArray);generated", - "kotlin.collections;UArraysKt;component4;(UIntArray);generated", - "kotlin.collections;UArraysKt;component4;(ULongArray);generated", - "kotlin.collections;UArraysKt;component4;(UShortArray);generated", - "kotlin.collections;UArraysKt;component5;(UByteArray);generated", - "kotlin.collections;UArraysKt;component5;(UIntArray);generated", - "kotlin.collections;UArraysKt;component5;(ULongArray);generated", - "kotlin.collections;UArraysKt;component5;(UShortArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UByteArray,UByteArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;contentEquals;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UByteArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UIntArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(ULongArray);generated", - "kotlin.collections;UArraysKt;contentHashCode;(UShortArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UIntArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;copyOf;(ULongArray);generated", - "kotlin.collections;UArraysKt;copyOf;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;copyOf;(UShortArray);generated", - "kotlin.collections;UArraysKt;copyOf;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;copyOfRange;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;count;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;count;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;dropWhile;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;elementAt;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;elementAt;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UByteArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UIntArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(ULongArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrElse;(UShortArray,int,Function1);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;elementAtOrNull;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;fill;(UByteArray,byte,int,int);generated", - "kotlin.collections;UArraysKt;fill;(UIntArray,int,int,int);generated", - "kotlin.collections;UArraysKt;fill;(ULongArray,long,int,int);generated", - "kotlin.collections;UArraysKt;fill;(UShortArray,short,int,int);generated", - "kotlin.collections;UArraysKt;filter;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;filter;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;filterIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;filterNot;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;filterNot;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;find;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;findLast;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UByteArray);generated", - "kotlin.collections;UArraysKt;first;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UIntArray);generated", - "kotlin.collections;UArraysKt;first;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(ULongArray);generated", - "kotlin.collections;UArraysKt;first;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;first;(UShortArray);generated", - "kotlin.collections;UArraysKt;first;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;firstOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMap;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;flatMapIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;forEach;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;forEach;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;forEachIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;getIndices;(UByteArray);generated", - "kotlin.collections;UArraysKt;getIndices;(UIntArray);generated", - "kotlin.collections;UArraysKt;getIndices;(ULongArray);generated", - "kotlin.collections;UArraysKt;getIndices;(UShortArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UByteArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UIntArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(ULongArray);generated", - "kotlin.collections;UArraysKt;getLastIndex;(UShortArray);generated", - "kotlin.collections;UArraysKt;getOrElse;(UByteArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(UIntArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(ULongArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrElse;(UShortArray,int,Function1);generated", - "kotlin.collections;UArraysKt;getOrNull;(UByteArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(ULongArray,int);generated", - "kotlin.collections;UArraysKt;getOrNull;(UShortArray,int);generated", - "kotlin.collections;UArraysKt;groupBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UByteArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UIntArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(ULongArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;groupBy;(UShortArray,Function1,Function1);generated", - "kotlin.collections;UArraysKt;indexOf;(UByteArray,byte);generated", - "kotlin.collections;UArraysKt;indexOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;indexOf;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;indexOf;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfFirst;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;indexOfLast;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UByteArray);generated", - "kotlin.collections;UArraysKt;last;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UIntArray);generated", - "kotlin.collections;UArraysKt;last;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(ULongArray);generated", - "kotlin.collections;UArraysKt;last;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;last;(UShortArray);generated", - "kotlin.collections;UArraysKt;last;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UByteArray,byte);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;lastIndexOf;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;lastOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;map;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;mapIndexed;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;max;(UByteArray);generated", - "kotlin.collections;UArraysKt;max;(UIntArray);generated", - "kotlin.collections;UArraysKt;max;(ULongArray);generated", - "kotlin.collections;UArraysKt;max;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxByOrThrow-U;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOf;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWith;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOfWithOrNull;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;maxOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UByteArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UIntArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(ULongArray);generated", - "kotlin.collections;UArraysKt;maxOrThrow-U;(UShortArray);generated", - "kotlin.collections;UArraysKt;maxWith;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWith;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrNull;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;maxWithOrThrow-U;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;min;(UByteArray);generated", - "kotlin.collections;UArraysKt;min;(UIntArray);generated", - "kotlin.collections;UArraysKt;min;(ULongArray);generated", - "kotlin.collections;UArraysKt;min;(UShortArray);generated", - "kotlin.collections;UArraysKt;minBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minByOrThrow-U;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minOf;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWith;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UByteArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UIntArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(ULongArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOfWithOrNull;(UShortArray,Comparator,Function1);generated", - "kotlin.collections;UArraysKt;minOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;minOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UByteArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UIntArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(ULongArray);generated", - "kotlin.collections;UArraysKt;minOrThrow-U;(UShortArray);generated", - "kotlin.collections;UArraysKt;minWith;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWith;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrNull;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UByteArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UIntArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(ULongArray,Comparator);generated", - "kotlin.collections;UArraysKt;minWithOrThrow-U;(UShortArray,Comparator);generated", - "kotlin.collections;UArraysKt;none;(UByteArray);generated", - "kotlin.collections;UArraysKt;none;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(UIntArray);generated", - "kotlin.collections;UArraysKt;none;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(ULongArray);generated", - "kotlin.collections;UArraysKt;none;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;none;(UShortArray);generated", - "kotlin.collections;UArraysKt;none;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;plus;(UIntArray,int);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;plus;(ULongArray,long);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,Collection);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;plus;(UShortArray,short);generated", - "kotlin.collections;UArraysKt;random;(UByteArray);generated", - "kotlin.collections;UArraysKt;random;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;random;(UIntArray);generated", - "kotlin.collections;UArraysKt;random;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;random;(ULongArray);generated", - "kotlin.collections;UArraysKt;random;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;random;(UShortArray);generated", - "kotlin.collections;UArraysKt;random;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;randomOrNull;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;reduce;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduce;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceIndexedOrNull;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceOrNull;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRight;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightIndexedOrNull;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;reduceRightOrNull;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;reverse;(UByteArray);generated", - "kotlin.collections;UArraysKt;reverse;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(UIntArray);generated", - "kotlin.collections;UArraysKt;reverse;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(ULongArray);generated", - "kotlin.collections;UArraysKt;reverse;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;reverse;(UShortArray);generated", - "kotlin.collections;UArraysKt;reverse;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;reversedArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;reversedArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;reversedArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;runningReduce;(UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduce;(UShortArray,Function2);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UByteArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UIntArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(ULongArray,Function3);generated", - "kotlin.collections;UArraysKt;runningReduceIndexed;(UShortArray,Function3);generated", - "kotlin.collections;UArraysKt;shuffle;(UByteArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UByteArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(UIntArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UIntArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(ULongArray);generated", - "kotlin.collections;UArraysKt;shuffle;(ULongArray,Random);generated", - "kotlin.collections;UArraysKt;shuffle;(UShortArray);generated", - "kotlin.collections;UArraysKt;shuffle;(UShortArray,Random);generated", - "kotlin.collections;UArraysKt;single;(UByteArray);generated", - "kotlin.collections;UArraysKt;single;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(UIntArray);generated", - "kotlin.collections;UArraysKt;single;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(ULongArray);generated", - "kotlin.collections;UArraysKt;single;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;single;(UShortArray);generated", - "kotlin.collections;UArraysKt;single;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UByteArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UIntArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(ULongArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UShortArray);generated", - "kotlin.collections;UArraysKt;singleOrNull;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;slice;(UByteArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UByteArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(UIntArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UIntArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(ULongArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(ULongArray,Iterable);generated", - "kotlin.collections;UArraysKt;slice;(UShortArray,IntRange);generated", - "kotlin.collections;UArraysKt;slice;(UShortArray,Iterable);generated", - "kotlin.collections;UArraysKt;sliceArray;(UByteArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UIntArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UIntArray,IntRange);generated", - "kotlin.collections;UArraysKt;sliceArray;(ULongArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(ULongArray,IntRange);generated", - "kotlin.collections;UArraysKt;sliceArray;(UShortArray,Collection);generated", - "kotlin.collections;UArraysKt;sliceArray;(UShortArray,IntRange);generated", - "kotlin.collections;UArraysKt;sort;(UByteArray);generated", - "kotlin.collections;UArraysKt;sort;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(UIntArray);generated", - "kotlin.collections;UArraysKt;sort;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(ULongArray);generated", - "kotlin.collections;UArraysKt;sort;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;sort;(UShortArray);generated", - "kotlin.collections;UArraysKt;sort;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UByteArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UByteArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UIntArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UIntArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(ULongArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(ULongArray,int,int);generated", - "kotlin.collections;UArraysKt;sortDescending;(UShortArray);generated", - "kotlin.collections;UArraysKt;sortDescending;(UShortArray,int,int);generated", - "kotlin.collections;UArraysKt;sorted;(UByteArray);generated", - "kotlin.collections;UArraysKt;sorted;(UIntArray);generated", - "kotlin.collections;UArraysKt;sorted;(ULongArray);generated", - "kotlin.collections;UArraysKt;sorted;(UShortArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(UIntArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(ULongArray);generated", - "kotlin.collections;UArraysKt;sortedDescending;(UShortArray);generated", - "kotlin.collections;UArraysKt;sum;(UByteArray);generated", - "kotlin.collections;UArraysKt;sum;(UIntArray);generated", - "kotlin.collections;UArraysKt;sum;(ULongArray);generated", - "kotlin.collections;UArraysKt;sum;(UShortArray);generated", - "kotlin.collections;UArraysKt;sumBy;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumBy;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumByDouble;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigDecimal;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfBigInteger;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfDouble;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfInt;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfLong;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUByte;(byte[]);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfUInt;(int[]);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;sumOfULong;(long[]);generated", - "kotlin.collections;UArraysKt;sumOfUShort;(short[]);generated", - "kotlin.collections;UArraysKt;takeWhile;(UByteArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(UIntArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(ULongArray,Function1);generated", - "kotlin.collections;UArraysKt;takeWhile;(UShortArray,Function1);generated", - "kotlin.collections;UArraysKt;toIntArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;toLongArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;toShortArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UByteArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UIntArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(ULongArray);generated", - "kotlin.collections;UArraysKt;toTypedArray;(UShortArray);generated", - "kotlin.collections;UArraysKt;toUIntArray;(int[]);generated", - "kotlin.collections;UArraysKt;toULongArray;(long[]);generated", - "kotlin.collections;UArraysKt;toUShortArray;(short[]);generated", - "kotlin.collections;UArraysKt;withIndex;(UByteArray);generated", - "kotlin.collections;UArraysKt;withIndex;(UIntArray);generated", - "kotlin.collections;UArraysKt;withIndex;(ULongArray);generated", - "kotlin.collections;UArraysKt;withIndex;(UShortArray);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,UByteArray);generated", - "kotlin.collections;UArraysKt;zip;(UByteArray,UByteArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,UIntArray);generated", - "kotlin.collections;UArraysKt;zip;(UIntArray,UIntArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,ULongArray);generated", - "kotlin.collections;UArraysKt;zip;(ULongArray,ULongArray,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Iterable);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Iterable,Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Object[]);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,Object[],Function2);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,UShortArray);generated", - "kotlin.collections;UArraysKt;zip;(UShortArray,UShortArray,Function2);generated", - "kotlin.collections;UCollectionsKt;sumOfUByte;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfUInt;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfULong;(Iterable);generated", - "kotlin.collections;UCollectionsKt;sumOfUShort;(Iterable);generated", - "kotlin.collections;UCollectionsKt;toUByteArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toUIntArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toULongArray;(Collection);generated", - "kotlin.collections;UCollectionsKt;toUShortArray;(Collection);generated", - "kotlin.comparisons;ComparisonsKt;compareBy;();generated", - "kotlin.comparisons;ComparisonsKt;compareBy;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareBy;(Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareByDescending;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareByDescending;(Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareValues;(Comparable,Comparable);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;compareValuesBy;(Object,Object,Function1);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(byte,byte[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double,double);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(double,double[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float,float);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(float,float[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int,int);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(int,int[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long,long);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(long,long[]);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short,short);generated", - "kotlin.comparisons;ComparisonsKt;maxOf;(short,short[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte,byte);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(byte,byte[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double,double);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(double,double[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float,float);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(float,float[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int,int);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(int,int[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long,long);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(long,long[]);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short,short);generated", - "kotlin.comparisons;ComparisonsKt;minOf;(short,short[]);generated", - "kotlin.comparisons;ComparisonsKt;naturalOrder;();generated", - "kotlin.comparisons;ComparisonsKt;nullsFirst;();generated", - "kotlin.comparisons;ComparisonsKt;nullsFirst;(Comparator);generated", - "kotlin.comparisons;ComparisonsKt;nullsLast;();generated", - "kotlin.comparisons;ComparisonsKt;nullsLast;(Comparator);generated", - "kotlin.comparisons;ComparisonsKt;reverseOrder;();generated", - "kotlin.comparisons;ComparisonsKt;then;(Comparator,Comparator);generated", - "kotlin.comparisons;ComparisonsKt;thenBy;(Comparator,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenBy;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenByDescending;(Comparator,Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenByDescending;(Comparator,Function1);generated", - "kotlin.comparisons;ComparisonsKt;thenComparator;(Comparator,Function2);generated", - "kotlin.comparisons;ComparisonsKt;thenDescending;(Comparator,Comparator);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,UByteArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(byte,byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,UIntArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,int);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(int,int,int);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,ULongArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,long);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(long,long,long);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,UShortArray);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,short);generated", - "kotlin.comparisons;UComparisonsKt;maxOf;(short,short,short);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,UByteArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(byte,byte,byte);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,UIntArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,int);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(int,int,int);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,ULongArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,long);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(long,long,long);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,UShortArray);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,short);generated", - "kotlin.comparisons;UComparisonsKt;minOf;(short,short,short);generated", - "kotlin.concurrent;LocksKt;read;(ReentrantReadWriteLock,Function0);generated", - "kotlin.concurrent;LocksKt;withLock;(Lock,Function0);generated", - "kotlin.concurrent;LocksKt;write;(ReentrantReadWriteLock,Function0);generated", - "kotlin.concurrent;ThreadsKt;getOrSet;(ThreadLocal,Function0);generated", - "kotlin.concurrent;ThreadsKt;thread;(boolean,boolean,ClassLoader,String,int,Function0);generated", - "kotlin.concurrent;TimersKt;fixedRateTimer;(String,boolean,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;fixedRateTimer;(String,boolean,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,Date,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,long,Function1);generated", - "kotlin.concurrent;TimersKt;schedule;(Timer,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;scheduleAtFixedRate;(Timer,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;scheduleAtFixedRate;(Timer,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;timer;(String,boolean,Date,long,Function1);generated", - "kotlin.concurrent;TimersKt;timer;(String,boolean,long,long,Function1);generated", - "kotlin.concurrent;TimersKt;timerTask;(Function1);generated", - "kotlin.contracts;ContractBuilder;callsInPlace;(Function,InvocationKind);generated", - "kotlin.contracts;ContractBuilder;returns;();generated", - "kotlin.contracts;ContractBuilder;returns;(Object);generated", - "kotlin.contracts;ContractBuilder;returnsNotNull;();generated", - "kotlin.contracts;ContractBuilderKt;contract;(Function1);generated", - "kotlin.contracts;ExperimentalContracts;ExperimentalContracts;();generated", - "kotlin.contracts;InvocationKind;valueOf;(String);generated", - "kotlin.contracts;InvocationKind;values;();generated", - "kotlin.contracts;SimpleEffect;implies;(boolean);generated", - "kotlin.coroutines.cancellation;CancellationException;CancellationException;();generated", - "kotlin.coroutines.cancellation;CancellationException;CancellationException;(String);generated", - "kotlin.coroutines.cancellation;CancellationExceptionHKt;CancellationException;(String,Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionHKt;CancellationException;(Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionKt;CancellationException;(String,Throwable);generated", - "kotlin.coroutines.cancellation;CancellationExceptionKt;CancellationException;(Throwable);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;createCoroutineUnintercepted;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;createCoroutineUnintercepted;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;intercepted;(Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;startCoroutineUninterceptedOrReturn;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;CoroutinesIntrinsicsHKt;startCoroutineUninterceptedOrReturn;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;createCoroutineUnintercepted;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;createCoroutineUnintercepted;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;getCOROUTINE_SUSPENDED;();generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;startCoroutineUninterceptedOrReturn;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;startCoroutineUninterceptedOrReturn;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;suspendCoroutineUninterceptedOrReturn;(Function1);generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;getCallerFrame;();generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;getStackTraceElement;();generated", - "kotlin.coroutines;Continuation;getContext;();generated", - "kotlin.coroutines;Continuation;resumeWith;(Result);generated", - "kotlin.coroutines;ContinuationInterceptor;interceptContinuation;(Continuation);generated", - "kotlin.coroutines;ContinuationInterceptor;releaseInterceptedContinuation;(Continuation);generated", - "kotlin.coroutines;ContinuationKt;Continuation;(CoroutineContext,Function1);generated", - "kotlin.coroutines;ContinuationKt;createCoroutine;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines;ContinuationKt;createCoroutine;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines;ContinuationKt;getCoroutineContext;();generated", - "kotlin.coroutines;ContinuationKt;resume;(Continuation,Object);generated", - "kotlin.coroutines;ContinuationKt;resumeWithException;(Continuation,Throwable);generated", - "kotlin.coroutines;ContinuationKt;startCoroutine;(SuspendFunction0,Continuation);generated", - "kotlin.coroutines;ContinuationKt;startCoroutine;(SuspendFunction1,Object,Continuation);generated", - "kotlin.coroutines;ContinuationKt;suspendCoroutine;(Function1);generated", - "kotlin.coroutines;CoroutineContext$Element;getKey;();generated", - "kotlin.coroutines;CoroutineContext;fold;(Object,Function2);generated", - "kotlin.coroutines;CoroutineContext;get;(Key);generated", - "kotlin.coroutines;CoroutineContext;minusKey;(Key);generated", - "kotlin.coroutines;EmptyCoroutineContext;hashCode;();generated", - "kotlin.coroutines;EmptyCoroutineContext;toString;();generated", - "kotlin.coroutines;RestrictsSuspension;RestrictsSuspension;();generated", - "kotlin.experimental;BitwiseOperationsKt;and;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;and;(short,short);generated", - "kotlin.experimental;BitwiseOperationsKt;inv;(byte);generated", - "kotlin.experimental;BitwiseOperationsKt;inv;(short);generated", - "kotlin.experimental;BitwiseOperationsKt;or;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;or;(short,short);generated", - "kotlin.experimental;BitwiseOperationsKt;xor;(byte,byte);generated", - "kotlin.experimental;BitwiseOperationsKt;xor;(short,short);generated", - "kotlin.experimental;ExperimentalTypeInference;ExperimentalTypeInference;();generated", - "kotlin.io;ByteStreamsKt;bufferedWriter;(OutputStream,Charset);generated", - "kotlin.io;ByteStreamsKt;iterator;(BufferedInputStream);generated", - "kotlin.io;ByteStreamsKt;writer;(OutputStream,Charset);generated", - "kotlin.io;ConsoleKt;print;(Object);generated", - "kotlin.io;ConsoleKt;print;(boolean);generated", - "kotlin.io;ConsoleKt;print;(byte);generated", "kotlin.io;ConsoleKt;print;(char);generated", - "kotlin.io;ConsoleKt;print;(char[]);generated", - "kotlin.io;ConsoleKt;print;(double);generated", - "kotlin.io;ConsoleKt;print;(float);generated", "kotlin.io;ConsoleKt;print;(int);generated", - "kotlin.io;ConsoleKt;print;(long);generated", "kotlin.io;ConsoleKt;print;(short);generated", - "kotlin.io;ConsoleKt;println;();generated", - "kotlin.io;ConsoleKt;println;(Object);generated", - "kotlin.io;ConsoleKt;println;(boolean);generated", - "kotlin.io;ConsoleKt;println;(byte);generated", - "kotlin.io;ConsoleKt;println;(char);generated", - "kotlin.io;ConsoleKt;println;(char[]);generated", - "kotlin.io;ConsoleKt;println;(double);generated", - "kotlin.io;ConsoleKt;println;(float);generated", - "kotlin.io;ConsoleKt;println;(int);generated", - "kotlin.io;ConsoleKt;println;(long);generated", - "kotlin.io;ConsoleKt;println;(short);generated", - "kotlin.io;ConsoleKt;readLine;();generated", "kotlin.io;ConsoleKt;readln;();generated", - "kotlin.io;ConsoleKt;readlnOrNull;();generated", - "kotlin.io;ConstantsKt;getDEFAULT_BUFFER_SIZE;();generated", - "kotlin.io;FileWalkDirection;valueOf;(String);generated", - "kotlin.io;FileWalkDirection;values;();generated", - "kotlin.io;FilesKt;appendBytes;(File,byte[]);generated", - "kotlin.io;FilesKt;appendText;(File,String,Charset);generated", - "kotlin.io;FilesKt;bufferedReader;(File,Charset,int);generated", - "kotlin.io;FilesKt;bufferedWriter;(File,Charset,int);generated", - "kotlin.io;FilesKt;copyRecursively;(File,File,boolean,Function2);generated", - "kotlin.io;FilesKt;createTempDir;(String,String,File);generated", - "kotlin.io;FilesKt;createTempFile;(String,String,File);generated", - "kotlin.io;FilesKt;deleteRecursively;(File);generated", - "kotlin.io;FilesKt;endsWith;(File,File);generated", - "kotlin.io;FilesKt;endsWith;(File,String);generated", - "kotlin.io;FilesKt;forEachBlock;(File,Function2);generated", - "kotlin.io;FilesKt;forEachBlock;(File,int,Function2);generated", - "kotlin.io;FilesKt;forEachLine;(File,Charset,Function1);generated", - "kotlin.io;FilesKt;getExtension;(File);generated", - "kotlin.io;FilesKt;getInvariantSeparatorsPath;(File);generated", - "kotlin.io;FilesKt;getNameWithoutExtension;(File);generated", - "kotlin.io;FilesKt;inputStream;(File);generated", - "kotlin.io;FilesKt;isRooted;(File);generated", - "kotlin.io;FilesKt;normalize;(File);generated", - "kotlin.io;FilesKt;outputStream;(File);generated", - "kotlin.io;FilesKt;printWriter;(File,Charset);generated", - "kotlin.io;FilesKt;readBytes;(File);generated", - "kotlin.io;FilesKt;readLines;(File,Charset);generated", - "kotlin.io;FilesKt;readText;(File,Charset);generated", - "kotlin.io;FilesKt;reader;(File,Charset);generated", - "kotlin.io;FilesKt;relativeTo;(File,File);generated", - "kotlin.io;FilesKt;relativeToOrNull;(File,File);generated", - "kotlin.io;FilesKt;startsWith;(File,File);generated", - "kotlin.io;FilesKt;startsWith;(File,String);generated", - "kotlin.io;FilesKt;toRelativeString;(File,File);generated", - "kotlin.io;FilesKt;useLines;(File,Charset,Function1);generated", - "kotlin.io;FilesKt;writeBytes;(File,byte[]);generated", - "kotlin.io;FilesKt;writeText;(File,String,Charset);generated", - "kotlin.io;FilesKt;writer;(File,Charset);generated", - "kotlin.io;IoHKt;print;(Object);generated", "kotlin.io;IoHKt;println;();generated", - "kotlin.io;IoHKt;println;(Object);generated", "kotlin.io;IoHKt;readln;();generated", - "kotlin.io;IoHKt;readlnOrNull;();generated", - "kotlin.io;OnErrorAction;valueOf;(String);generated", - "kotlin.io;OnErrorAction;values;();generated", - "kotlin.io;TextStreamsKt;readBytes;(URL);generated", - "kotlin.io;TextStreamsKt;readLines;(Reader);generated", - "kotlin.io;TextStreamsKt;readText;(URL,Charset);generated", - "kotlin.js;ExperimentalJsExport;ExperimentalJsExport;();generated", - "kotlin.js;JsExport;JsExport;();generated", "kotlin.js;JsName;JsName;(String);generated", - "kotlin.js;JsName;name;();generated", "kotlin.jvm.functions;Function0;invoke;();generated", - "kotlin.jvm.functions;Function10;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function11;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function12;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function13;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function14;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function15;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function16;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function17;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function18;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function19;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function1;invoke;(Object);generated", - "kotlin.jvm.functions;Function20;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function21;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function22;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function2;invoke;(Object,Object);generated", - "kotlin.jvm.functions;Function3;invoke;(Object,Object,Object);generated", - "kotlin.jvm.functions;Function4;invoke;(Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function5;invoke;(Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function6;invoke;(Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function7;invoke;(Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function8;invoke;(Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;Function9;invoke;(Object,Object,Object,Object,Object,Object,Object,Object,Object);generated", - "kotlin.jvm.functions;FunctionN;invoke;(Object[]);generated", - "kotlin.jvm.internal;AdaptedFunctionReference;equals;(Object);generated", - "kotlin.jvm.internal;AdaptedFunctionReference;getOwner;();generated", - "kotlin.jvm.internal;AdaptedFunctionReference;hashCode;();generated", - "kotlin.jvm.internal;AdaptedFunctionReference;toString;();generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(boolean[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(double[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(float[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(int[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(long[]);generated", - "kotlin.jvm.internal;ArrayIteratorsKt;iterator;(short[]);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;BooleanSpreadBuilder;(int);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;add;(boolean);generated", - "kotlin.jvm.internal;BooleanSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;ByteSpreadBuilder;ByteSpreadBuilder;(int);generated", - "kotlin.jvm.internal;ByteSpreadBuilder;add;(byte);generated", - "kotlin.jvm.internal;CallableReference;CallableReference;();generated", - "kotlin.jvm.internal;CallableReference;getOwner;();generated", - "kotlin.jvm.internal;CharSpreadBuilder;CharSpreadBuilder;(int);generated", - "kotlin.jvm.internal;CharSpreadBuilder;add;(char);generated", - "kotlin.jvm.internal;ClassBasedDeclarationContainer;getJClass;();generated", - "kotlin.jvm.internal;ClassReference$Companion;isInstance;(Object,Class);generated", - "kotlin.jvm.internal;ClassReference;ClassReference;(Class);generated", - "kotlin.jvm.internal;ClassReference;equals;(Object);generated", - "kotlin.jvm.internal;ClassReference;hashCode;();generated", - "kotlin.jvm.internal;ClassReference;toString;();generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;DoubleSpreadBuilder;(int);generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;add;(double);generated", - "kotlin.jvm.internal;DoubleSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;FloatSpreadBuilder;FloatSpreadBuilder;(int);generated", - "kotlin.jvm.internal;FloatSpreadBuilder;add;(float);generated", - "kotlin.jvm.internal;FloatSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;FunInterfaceConstructorReference;(Class);generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;equals;(Object);generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;hashCode;();generated", - "kotlin.jvm.internal;FunInterfaceConstructorReference;toString;();generated", - "kotlin.jvm.internal;FunctionAdapter;getFunctionDelegate;();generated", - "kotlin.jvm.internal;FunctionBase;getArity;();generated", - "kotlin.jvm.internal;FunctionImpl;FunctionImpl;();generated", - "kotlin.jvm.internal;FunctionImpl;getArity;();generated", - "kotlin.jvm.internal;FunctionImpl;invokeVararg;(Object[]);generated", - "kotlin.jvm.internal;FunctionReference;FunctionReference;(int);generated", - "kotlin.jvm.internal;FunctionReference;equals;(Object);generated", - "kotlin.jvm.internal;FunctionReference;hashCode;();generated", - "kotlin.jvm.internal;InlineMarker;InlineMarker;();generated", - "kotlin.jvm.internal;InlineMarker;afterInlineCall;();generated", - "kotlin.jvm.internal;InlineMarker;beforeInlineCall;();generated", - "kotlin.jvm.internal;InlineMarker;finallyEnd;(int);generated", - "kotlin.jvm.internal;InlineMarker;finallyStart;(int);generated", - "kotlin.jvm.internal;InlineMarker;mark;(String);generated", - "kotlin.jvm.internal;InlineMarker;mark;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;IntSpreadBuilder;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;add;(int);generated", - "kotlin.jvm.internal;IntSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Double,Double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Double,double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Float,Float);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Float,float);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(Object,Object);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(double,Double);generated", - "kotlin.jvm.internal;Intrinsics;areEqual;(float,Float);generated", - "kotlin.jvm.internal;Intrinsics;checkExpressionValueIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkFieldIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkFieldIsNotNull;(Object,String,String);generated", - "kotlin.jvm.internal;Intrinsics;checkHasClass;(String);generated", - "kotlin.jvm.internal;Intrinsics;checkHasClass;(String,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNull;(Object);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNullExpressionValue;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkNotNullParameter;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkParameterIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkReturnedValueIsNotNull;(Object,String);generated", - "kotlin.jvm.internal;Intrinsics;checkReturnedValueIsNotNull;(Object,String,String);generated", - "kotlin.jvm.internal;Intrinsics;compare;(int,int);generated", - "kotlin.jvm.internal;Intrinsics;compare;(long,long);generated", - "kotlin.jvm.internal;Intrinsics;needClassReification;();generated", - "kotlin.jvm.internal;Intrinsics;needClassReification;(String);generated", - "kotlin.jvm.internal;Intrinsics;reifiedOperationMarker;(int,String);generated", - "kotlin.jvm.internal;Intrinsics;reifiedOperationMarker;(int,String,String);generated", - "kotlin.jvm.internal;Intrinsics;throwAssert;();generated", - "kotlin.jvm.internal;Intrinsics;throwAssert;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalArgument;();generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalArgument;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalState;();generated", - "kotlin.jvm.internal;Intrinsics;throwIllegalState;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwJavaNpe;();generated", - "kotlin.jvm.internal;Intrinsics;throwJavaNpe;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwNpe;();generated", - "kotlin.jvm.internal;Intrinsics;throwNpe;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUndefinedForReified;();generated", - "kotlin.jvm.internal;Intrinsics;throwUndefinedForReified;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUninitializedProperty;(String);generated", - "kotlin.jvm.internal;Intrinsics;throwUninitializedPropertyAccessException;(String);generated", - "kotlin.jvm.internal;KTypeBase;getJavaType;();generated", - "kotlin.jvm.internal;Lambda;Lambda;(int);generated", - "kotlin.jvm.internal;Lambda;toString;();generated", - "kotlin.jvm.internal;LocalVariableReference;LocalVariableReference;();generated", - "kotlin.jvm.internal;LongSpreadBuilder;LongSpreadBuilder;(int);generated", - "kotlin.jvm.internal;LongSpreadBuilder;add;(long);generated", - "kotlin.jvm.internal;LongSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;MagicApiIntrinsics;MagicApiIntrinsics;();generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,Object,Object,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;anyMagicApiCall;(int,long,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,Object,Object,Object,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;intMagicApiCall;(int,long,long,Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;voidMagicApiCall;(Object);generated", - "kotlin.jvm.internal;MagicApiIntrinsics;voidMagicApiCall;(int);generated", - "kotlin.jvm.internal;MutableLocalVariableReference;MutableLocalVariableReference;();generated", - "kotlin.jvm.internal;MutablePropertyReference0;MutablePropertyReference0;();generated", - "kotlin.jvm.internal;MutablePropertyReference1;MutablePropertyReference1;();generated", - "kotlin.jvm.internal;MutablePropertyReference2;MutablePropertyReference2;();generated", - "kotlin.jvm.internal;MutablePropertyReference;MutablePropertyReference;();generated", - "kotlin.jvm.internal;PackageReference;equals;(Object);generated", - "kotlin.jvm.internal;PackageReference;hashCode;();generated", - "kotlin.jvm.internal;PackageReference;toString;();generated", - "kotlin.jvm.internal;PrimitiveSpreadBuilder;PrimitiveSpreadBuilder;(int);generated", - "kotlin.jvm.internal;PropertyReference0;PropertyReference0;();generated", - "kotlin.jvm.internal;PropertyReference1;PropertyReference1;();generated", - "kotlin.jvm.internal;PropertyReference2;PropertyReference2;();generated", - "kotlin.jvm.internal;PropertyReference;PropertyReference;();generated", - "kotlin.jvm.internal;PropertyReference;equals;(Object);generated", - "kotlin.jvm.internal;PropertyReference;hashCode;();generated", - "kotlin.jvm.internal;Ref$BooleanRef;BooleanRef;();generated", - "kotlin.jvm.internal;Ref$BooleanRef;toString;();generated", - "kotlin.jvm.internal;Ref$ByteRef;ByteRef;();generated", - "kotlin.jvm.internal;Ref$ByteRef;toString;();generated", - "kotlin.jvm.internal;Ref$CharRef;CharRef;();generated", - "kotlin.jvm.internal;Ref$CharRef;toString;();generated", - "kotlin.jvm.internal;Ref$DoubleRef;DoubleRef;();generated", - "kotlin.jvm.internal;Ref$DoubleRef;toString;();generated", - "kotlin.jvm.internal;Ref$FloatRef;FloatRef;();generated", - "kotlin.jvm.internal;Ref$FloatRef;toString;();generated", - "kotlin.jvm.internal;Ref$IntRef;IntRef;();generated", - "kotlin.jvm.internal;Ref$IntRef;toString;();generated", - "kotlin.jvm.internal;Ref$LongRef;LongRef;();generated", - "kotlin.jvm.internal;Ref$LongRef;toString;();generated", - "kotlin.jvm.internal;Ref$ObjectRef;ObjectRef;();generated", - "kotlin.jvm.internal;Ref$ObjectRef;toString;();generated", - "kotlin.jvm.internal;Ref$ShortRef;ShortRef;();generated", - "kotlin.jvm.internal;Ref$ShortRef;toString;();generated", - "kotlin.jvm.internal;Reflection;Reflection;();generated", - "kotlin.jvm.internal;Reflection;createKotlinClass;(Class);generated", - "kotlin.jvm.internal;Reflection;createKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClass;(Class);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinClasses;(Class[]);generated", - "kotlin.jvm.internal;Reflection;getOrCreateKotlinPackage;(Class);generated", - "kotlin.jvm.internal;Reflection;nullableTypeOf;(Class);generated", - "kotlin.jvm.internal;Reflection;nullableTypeOf;(Class,KTypeProjection[]);generated", - "kotlin.jvm.internal;Reflection;renderLambdaToString;(FunctionBase);generated", - "kotlin.jvm.internal;Reflection;renderLambdaToString;(Lambda);generated", - "kotlin.jvm.internal;Reflection;setUpperBounds;(KTypeParameter,KType[]);generated", - "kotlin.jvm.internal;Reflection;typeOf;(Class);generated", - "kotlin.jvm.internal;Reflection;typeOf;(Class,KTypeProjection[]);generated", - "kotlin.jvm.internal;ReflectionFactory;ReflectionFactory;();generated", - "kotlin.jvm.internal;ReflectionFactory;createKotlinClass;(Class);generated", - "kotlin.jvm.internal;ReflectionFactory;createKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;ReflectionFactory;getOrCreateKotlinClass;(Class);generated", - "kotlin.jvm.internal;ReflectionFactory;getOrCreateKotlinClass;(Class,String);generated", - "kotlin.jvm.internal;ReflectionFactory;renderLambdaToString;(FunctionBase);generated", - "kotlin.jvm.internal;ReflectionFactory;renderLambdaToString;(Lambda);generated", - "kotlin.jvm.internal;SerializedIr;SerializedIr;(String[]);generated", - "kotlin.jvm.internal;SerializedIr;b;();generated", - "kotlin.jvm.internal;ShortSpreadBuilder;ShortSpreadBuilder;(int);generated", - "kotlin.jvm.internal;ShortSpreadBuilder;add;(short);generated", - "kotlin.jvm.internal;ShortSpreadBuilder;toArray;();generated", - "kotlin.jvm.internal;SpreadBuilder;SpreadBuilder;(int);generated", - "kotlin.jvm.internal;SpreadBuilder;size;();generated", - "kotlin.jvm.internal;TypeIntrinsics;TypeIntrinsics;();generated", - "kotlin.jvm.internal;TypeIntrinsics;getFunctionArity;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isFunctionOfArity;(Object,int);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableCollection;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableIterable;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableIterator;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableList;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableListIterator;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableMap;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableMapEntry;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;isMutableSet;(Object);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(ClassCastException);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(Object,String);generated", - "kotlin.jvm.internal;TypeIntrinsics;throwCce;(String);generated", - "kotlin.jvm.internal;TypeParameterReference$Companion;toString;(KTypeParameter);generated", - "kotlin.jvm.internal;TypeParameterReference;equals;(Object);generated", - "kotlin.jvm.internal;TypeParameterReference;hashCode;();generated", - "kotlin.jvm.internal;TypeParameterReference;toString;();generated", - "kotlin.jvm.internal;TypeReference;equals;(Object);generated", - "kotlin.jvm.internal;TypeReference;hashCode;();generated", - "kotlin.jvm;JvmClassMappingKt;getAnnotationClass;(Annotation);generated", - "kotlin.jvm;JvmClassMappingKt;getDeclaringJavaClass;(Enum);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaClass;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaClass;(Object);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaObjectType;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getJavaPrimitiveType;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;getKotlinClass;(Class);generated", - "kotlin.jvm;JvmClassMappingKt;getRuntimeClassOfKClassInstance;(KClass);generated", - "kotlin.jvm;JvmClassMappingKt;isArrayOf;(Object[]);generated", - "kotlin.jvm;JvmDefault;JvmDefault;();generated", - "kotlin.jvm;JvmDefaultWithCompatibility;JvmDefaultWithCompatibility;();generated", - "kotlin.jvm;JvmDefaultWithoutCompatibility;JvmDefaultWithoutCompatibility;();generated", - "kotlin.jvm;JvmField;JvmField;();generated", "kotlin.jvm;JvmInline;JvmInline;();generated", - "kotlin.jvm;JvmMultifileClass;JvmMultifileClass;();generated", - "kotlin.jvm;JvmName;JvmName;(String);generated", "kotlin.jvm;JvmName;name;();generated", - "kotlin.jvm;JvmOverloads;JvmOverloads;();generated", - "kotlin.jvm;JvmRecord;JvmRecord;();generated", - "kotlin.jvm;JvmStatic;JvmStatic;();generated", - "kotlin.jvm;JvmSuppressWildcards;JvmSuppressWildcards;(boolean);generated", - "kotlin.jvm;JvmSuppressWildcards;suppress;();generated", - "kotlin.jvm;JvmSynthetic;JvmSynthetic;();generated", - "kotlin.jvm;JvmWildcard;JvmWildcard;();generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;();generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(String);generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(String,Throwable);generated", - "kotlin.jvm;KotlinReflectionNotSupportedError;KotlinReflectionNotSupportedError;(Throwable);generated", - "kotlin.jvm;PurelyImplements;PurelyImplements;(String);generated", - "kotlin.jvm;PurelyImplements;value;();generated", - "kotlin.jvm;Strictfp;Strictfp;();generated", - "kotlin.jvm;Synchronized;Synchronized;();generated", - "kotlin.jvm;Throws;Throws;(KClass[]);generated", - "kotlin.jvm;Throws;exceptionClasses;();generated", - "kotlin.jvm;Transient;Transient;();generated", "kotlin.jvm;Volatile;Volatile;();generated", - "kotlin.math;MathKt;IEEErem;(double,double);generated", - "kotlin.math;MathKt;IEEErem;(float,float);generated", - "kotlin.math;MathKt;abs;(double);generated", "kotlin.math;MathKt;abs;(float);generated", - "kotlin.math;MathKt;abs;(int);generated", "kotlin.math;MathKt;abs;(long);generated", - "kotlin.math;MathKt;acos;(double);generated", "kotlin.math;MathKt;acos;(float);generated", - "kotlin.math;MathKt;acosh;(double);generated", "kotlin.math;MathKt;acosh;(float);generated", - "kotlin.math;MathKt;asin;(double);generated", "kotlin.math;MathKt;asin;(float);generated", - "kotlin.math;MathKt;asinh;(double);generated", "kotlin.math;MathKt;asinh;(float);generated", - "kotlin.math;MathKt;atan2;(double,double);generated", - "kotlin.math;MathKt;atan2;(float,float);generated", - "kotlin.math;MathKt;atan;(double);generated", "kotlin.math;MathKt;atan;(float);generated", - "kotlin.math;MathKt;atanh;(double);generated", "kotlin.math;MathKt;atanh;(float);generated", - "kotlin.math;MathKt;cbrt;(double);generated", "kotlin.math;MathKt;cbrt;(float);generated", - "kotlin.math;MathKt;ceil;(double);generated", "kotlin.math;MathKt;ceil;(float);generated", - "kotlin.math;MathKt;cos;(double);generated", "kotlin.math;MathKt;cos;(float);generated", - "kotlin.math;MathKt;cosh;(double);generated", "kotlin.math;MathKt;cosh;(float);generated", - "kotlin.math;MathKt;exp;(double);generated", "kotlin.math;MathKt;exp;(float);generated", - "kotlin.math;MathKt;expm1;(double);generated", "kotlin.math;MathKt;expm1;(float);generated", - "kotlin.math;MathKt;floor;(double);generated", "kotlin.math;MathKt;floor;(float);generated", - "kotlin.math;MathKt;getAbsoluteValue;(double);generated", - "kotlin.math;MathKt;getAbsoluteValue;(float);generated", - "kotlin.math;MathKt;getAbsoluteValue;(int);generated", - "kotlin.math;MathKt;getAbsoluteValue;(long);generated", - "kotlin.math;MathKt;getE;();generated", "kotlin.math;MathKt;getPI;();generated", - "kotlin.math;MathKt;getSign;(double);generated", - "kotlin.math;MathKt;getSign;(float);generated", - "kotlin.math;MathKt;getSign;(int);generated", "kotlin.math;MathKt;getSign;(long);generated", - "kotlin.math;MathKt;getUlp;(double);generated", - "kotlin.math;MathKt;getUlp;(float);generated", - "kotlin.math;MathKt;hypot;(double,double);generated", - "kotlin.math;MathKt;hypot;(float,float);generated", - "kotlin.math;MathKt;ln1p;(double);generated", "kotlin.math;MathKt;ln1p;(float);generated", - "kotlin.math;MathKt;ln;(double);generated", "kotlin.math;MathKt;ln;(float);generated", - "kotlin.math;MathKt;log10;(double);generated", "kotlin.math;MathKt;log10;(float);generated", - "kotlin.math;MathKt;log2;(double);generated", "kotlin.math;MathKt;log2;(float);generated", - "kotlin.math;MathKt;log;(double,double);generated", - "kotlin.math;MathKt;log;(float,float);generated", - "kotlin.math;MathKt;max;(double,double);generated", - "kotlin.math;MathKt;max;(float,float);generated", - "kotlin.math;MathKt;max;(int,int);generated", - "kotlin.math;MathKt;max;(long,long);generated", - "kotlin.math;MathKt;min;(double,double);generated", - "kotlin.math;MathKt;min;(float,float);generated", - "kotlin.math;MathKt;min;(int,int);generated", - "kotlin.math;MathKt;min;(long,long);generated", - "kotlin.math;MathKt;nextDown;(double);generated", - "kotlin.math;MathKt;nextDown;(float);generated", - "kotlin.math;MathKt;nextTowards;(double,double);generated", - "kotlin.math;MathKt;nextTowards;(float,float);generated", - "kotlin.math;MathKt;nextUp;(double);generated", - "kotlin.math;MathKt;nextUp;(float);generated", - "kotlin.math;MathKt;pow;(double,double);generated", - "kotlin.math;MathKt;pow;(double,int);generated", - "kotlin.math;MathKt;pow;(float,float);generated", - "kotlin.math;MathKt;pow;(float,int);generated", - "kotlin.math;MathKt;round;(double);generated", "kotlin.math;MathKt;round;(float);generated", - "kotlin.math;MathKt;roundToInt;(double);generated", - "kotlin.math;MathKt;roundToInt;(float);generated", - "kotlin.math;MathKt;roundToLong;(double);generated", - "kotlin.math;MathKt;roundToLong;(float);generated", - "kotlin.math;MathKt;sign;(double);generated", "kotlin.math;MathKt;sign;(float);generated", - "kotlin.math;MathKt;sin;(double);generated", "kotlin.math;MathKt;sin;(float);generated", - "kotlin.math;MathKt;sinh;(double);generated", "kotlin.math;MathKt;sinh;(float);generated", - "kotlin.math;MathKt;sqrt;(double);generated", "kotlin.math;MathKt;sqrt;(float);generated", - "kotlin.math;MathKt;tan;(double);generated", "kotlin.math;MathKt;tan;(float);generated", - "kotlin.math;MathKt;tanh;(double);generated", "kotlin.math;MathKt;tanh;(float);generated", - "kotlin.math;MathKt;truncate;(double);generated", - "kotlin.math;MathKt;truncate;(float);generated", - "kotlin.math;MathKt;withSign;(double,double);generated", - "kotlin.math;MathKt;withSign;(double,int);generated", - "kotlin.math;MathKt;withSign;(float,float);generated", - "kotlin.math;MathKt;withSign;(float,int);generated", - "kotlin.math;UMathKt;max;(int,int);generated", - "kotlin.math;UMathKt;max;(long,long);generated", - "kotlin.math;UMathKt;min;(int,int);generated", - "kotlin.math;UMathKt;min;(long,long);generated", - "kotlin.native.concurrent;SharedImmutable;SharedImmutable;();generated", - "kotlin.native.concurrent;ThreadLocal;ThreadLocal;();generated", - "kotlin.native;CName;CName;(String,String);generated", - "kotlin.native;CName;externName;();generated", "kotlin.native;CName;shortName;();generated", - "kotlin.properties;Delegates;notNull;();generated", - "kotlin.properties;Delegates;observable;(Object,Function3);generated", - "kotlin.properties;Delegates;vetoable;(Object,Function3);generated", - "kotlin.properties;PropertyDelegateProvider;provideDelegate;(Object,KProperty);generated", - "kotlin.properties;ReadOnlyProperty;getValue;(Object,KProperty);generated", - "kotlin.properties;ReadWriteProperty;setValue;(Object,KProperty,Object);generated", - "kotlin.random;Random;Random;();generated", "kotlin.random;Random;nextBits;(int);generated", - "kotlin.random;Random;nextBoolean;();generated", - "kotlin.random;Random;nextBytes;(int);generated", - "kotlin.random;Random;nextDouble;();generated", - "kotlin.random;Random;nextDouble;(double);generated", - "kotlin.random;Random;nextDouble;(double,double);generated", - "kotlin.random;Random;nextFloat;();generated", "kotlin.random;Random;nextInt;();generated", - "kotlin.random;Random;nextInt;(int);generated", - "kotlin.random;Random;nextInt;(int,int);generated", - "kotlin.random;Random;nextLong;();generated", - "kotlin.random;Random;nextLong;(long);generated", - "kotlin.random;Random;nextLong;(long,long);generated", - "kotlin.random;RandomKt;Random;(int);generated", - "kotlin.random;RandomKt;Random;(long);generated", - "kotlin.random;RandomKt;nextInt;(Random,IntRange);generated", - "kotlin.random;RandomKt;nextLong;(Random,LongRange);generated", - "kotlin.random;URandomKt;nextUBytes;(Random,int);generated", - "kotlin.random;URandomKt;nextUInt;(Random);generated", - "kotlin.random;URandomKt;nextUInt;(Random,UIntRange);generated", - "kotlin.random;URandomKt;nextUInt;(Random,int);generated", - "kotlin.random;URandomKt;nextUInt;(Random,int,int);generated", - "kotlin.random;URandomKt;nextULong;(Random);generated", - "kotlin.random;URandomKt;nextULong;(Random,ULongRange);generated", - "kotlin.random;URandomKt;nextULong;(Random,long);generated", - "kotlin.random;URandomKt;nextULong;(Random,long,long);generated", - "kotlin.ranges;CharProgression$Companion;fromClosedRange;(char,char,int);generated", - "kotlin.ranges;CharProgression;equals;(Object);generated", - "kotlin.ranges;CharProgression;getFirst;();generated", - "kotlin.ranges;CharProgression;getLast;();generated", - "kotlin.ranges;CharProgression;getStep;();generated", - "kotlin.ranges;CharProgression;hashCode;();generated", - "kotlin.ranges;CharProgression;isEmpty;();generated", - "kotlin.ranges;CharProgression;toString;();generated", - "kotlin.ranges;CharRange;CharRange;(char,char);generated", - "kotlin.ranges;CharRange;contains;(char);generated", - "kotlin.ranges;CharRange;equals;(Object);generated", - "kotlin.ranges;CharRange;hashCode;();generated", - "kotlin.ranges;CharRange;toString;();generated", - "kotlin.ranges;ClosedFloatingPointRange;lessThanOrEquals;(Comparable,Comparable);generated", - "kotlin.ranges;ClosedRange;contains;(Comparable);generated", - "kotlin.ranges;ClosedRange;getEndInclusive;();generated", - "kotlin.ranges;ClosedRange;getStart;();generated", - "kotlin.ranges;ClosedRange;isEmpty;();generated", - "kotlin.ranges;IntProgression$Companion;fromClosedRange;(int,int,int);generated", - "kotlin.ranges;IntProgression;equals;(Object);generated", - "kotlin.ranges;IntProgression;getFirst;();generated", - "kotlin.ranges;IntProgression;getLast;();generated", - "kotlin.ranges;IntProgression;getStep;();generated", - "kotlin.ranges;IntProgression;hashCode;();generated", - "kotlin.ranges;IntProgression;isEmpty;();generated", - "kotlin.ranges;IntProgression;toString;();generated", - "kotlin.ranges;IntRange;IntRange;(int,int);generated", - "kotlin.ranges;IntRange;contains;(int);generated", - "kotlin.ranges;IntRange;equals;(Object);generated", - "kotlin.ranges;IntRange;hashCode;();generated", - "kotlin.ranges;IntRange;toString;();generated", - "kotlin.ranges;LongProgression$Companion;fromClosedRange;(long,long,long);generated", - "kotlin.ranges;LongProgression;equals;(Object);generated", - "kotlin.ranges;LongProgression;getFirst;();generated", - "kotlin.ranges;LongProgression;getLast;();generated", - "kotlin.ranges;LongProgression;getStep;();generated", - "kotlin.ranges;LongProgression;hashCode;();generated", - "kotlin.ranges;LongProgression;isEmpty;();generated", - "kotlin.ranges;LongProgression;toString;();generated", - "kotlin.ranges;LongRange;LongRange;(long,long);generated", - "kotlin.ranges;LongRange;contains;(long);generated", - "kotlin.ranges;LongRange;equals;(Object);generated", - "kotlin.ranges;LongRange;hashCode;();generated", - "kotlin.ranges;LongRange;toString;();generated", - "kotlin.ranges;OpenEndRange;contains;(Comparable);generated", - "kotlin.ranges;OpenEndRange;getEndExclusive;();generated", - "kotlin.ranges;OpenEndRange;getStart;();generated", - "kotlin.ranges;OpenEndRange;isEmpty;();generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;byteRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(byte,byte);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(double,double);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(float,float);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(int,int);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(long,long);generated", - "kotlin.ranges;RangesKt;coerceAtLeast;(short,short);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(byte,byte);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(double,double);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(float,float);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(int,int);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(long,long);generated", - "kotlin.ranges;RangesKt;coerceAtMost;(short,short);generated", - "kotlin.ranges;RangesKt;coerceIn;(byte,byte,byte);generated", - "kotlin.ranges;RangesKt;coerceIn;(double,double,double);generated", - "kotlin.ranges;RangesKt;coerceIn;(float,float,float);generated", - "kotlin.ranges;RangesKt;coerceIn;(int,ClosedRange);generated", - "kotlin.ranges;RangesKt;coerceIn;(int,int,int);generated", - "kotlin.ranges;RangesKt;coerceIn;(long,ClosedRange);generated", - "kotlin.ranges;RangesKt;coerceIn;(long,long,long);generated", - "kotlin.ranges;RangesKt;coerceIn;(short,short,short);generated", - "kotlin.ranges;RangesKt;contains;(CharRange,Character);generated", - "kotlin.ranges;RangesKt;contains;(ClosedRange,Object);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,Integer);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,byte);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,long);generated", - "kotlin.ranges;RangesKt;contains;(IntRange,short);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,Long);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,byte);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,int);generated", - "kotlin.ranges;RangesKt;contains;(LongRange,short);generated", - "kotlin.ranges;RangesKt;contains;(OpenEndRange,Object);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;doubleRangeContains;(OpenEndRange,float);generated", - "kotlin.ranges;RangesKt;downTo;(byte,byte);generated", - "kotlin.ranges;RangesKt;downTo;(byte,int);generated", - "kotlin.ranges;RangesKt;downTo;(byte,long);generated", - "kotlin.ranges;RangesKt;downTo;(byte,short);generated", - "kotlin.ranges;RangesKt;downTo;(char,char);generated", - "kotlin.ranges;RangesKt;downTo;(int,byte);generated", - "kotlin.ranges;RangesKt;downTo;(int,int);generated", - "kotlin.ranges;RangesKt;downTo;(int,long);generated", - "kotlin.ranges;RangesKt;downTo;(int,short);generated", - "kotlin.ranges;RangesKt;downTo;(long,byte);generated", - "kotlin.ranges;RangesKt;downTo;(long,int);generated", - "kotlin.ranges;RangesKt;downTo;(long,long);generated", - "kotlin.ranges;RangesKt;downTo;(long,short);generated", - "kotlin.ranges;RangesKt;downTo;(short,byte);generated", - "kotlin.ranges;RangesKt;downTo;(short,int);generated", - "kotlin.ranges;RangesKt;downTo;(short,long);generated", - "kotlin.ranges;RangesKt;downTo;(short,short);generated", - "kotlin.ranges;RangesKt;first;(CharProgression);generated", - "kotlin.ranges;RangesKt;first;(IntProgression);generated", - "kotlin.ranges;RangesKt;first;(LongProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(CharProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(IntProgression);generated", - "kotlin.ranges;RangesKt;firstOrNull;(LongProgression);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;floatRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;intRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;intRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;last;(CharProgression);generated", - "kotlin.ranges;RangesKt;last;(IntProgression);generated", - "kotlin.ranges;RangesKt;last;(LongProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(CharProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(IntProgression);generated", - "kotlin.ranges;RangesKt;lastOrNull;(LongProgression);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;longRangeContains;(ClosedRange,short);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;longRangeContains;(OpenEndRange,short);generated", - "kotlin.ranges;RangesKt;random;(CharRange);generated", - "kotlin.ranges;RangesKt;random;(CharRange,Random);generated", - "kotlin.ranges;RangesKt;random;(IntRange);generated", - "kotlin.ranges;RangesKt;random;(IntRange,Random);generated", - "kotlin.ranges;RangesKt;random;(LongRange);generated", - "kotlin.ranges;RangesKt;random;(LongRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(CharRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(CharRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(IntRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(IntRange,Random);generated", - "kotlin.ranges;RangesKt;randomOrNull;(LongRange);generated", - "kotlin.ranges;RangesKt;randomOrNull;(LongRange,Random);generated", - "kotlin.ranges;RangesKt;rangeTo;(double,double);generated", - "kotlin.ranges;RangesKt;rangeTo;(float,float);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(byte,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(char,char);generated", - "kotlin.ranges;RangesKt;rangeUntil;(double,double);generated", - "kotlin.ranges;RangesKt;rangeUntil;(float,float);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(int,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(long,short);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,byte);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,int);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,long);generated", - "kotlin.ranges;RangesKt;rangeUntil;(short,short);generated", - "kotlin.ranges;RangesKt;reversed;(CharProgression);generated", - "kotlin.ranges;RangesKt;reversed;(IntProgression);generated", - "kotlin.ranges;RangesKt;reversed;(LongProgression);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,byte);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,double);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,float);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,int);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(ClosedRange,long);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,byte);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,int);generated", - "kotlin.ranges;RangesKt;shortRangeContains;(OpenEndRange,long);generated", - "kotlin.ranges;RangesKt;step;(CharProgression,int);generated", - "kotlin.ranges;RangesKt;step;(IntProgression,int);generated", - "kotlin.ranges;RangesKt;step;(LongProgression,long);generated", - "kotlin.ranges;RangesKt;until;(byte,byte);generated", - "kotlin.ranges;RangesKt;until;(byte,int);generated", - "kotlin.ranges;RangesKt;until;(byte,long);generated", - "kotlin.ranges;RangesKt;until;(byte,short);generated", - "kotlin.ranges;RangesKt;until;(char,char);generated", - "kotlin.ranges;RangesKt;until;(int,byte);generated", - "kotlin.ranges;RangesKt;until;(int,int);generated", - "kotlin.ranges;RangesKt;until;(int,long);generated", - "kotlin.ranges;RangesKt;until;(int,short);generated", - "kotlin.ranges;RangesKt;until;(long,byte);generated", - "kotlin.ranges;RangesKt;until;(long,int);generated", - "kotlin.ranges;RangesKt;until;(long,long);generated", - "kotlin.ranges;RangesKt;until;(long,short);generated", - "kotlin.ranges;RangesKt;until;(short,byte);generated", - "kotlin.ranges;RangesKt;until;(short,int);generated", - "kotlin.ranges;RangesKt;until;(short,long);generated", - "kotlin.ranges;RangesKt;until;(short,short);generated", - "kotlin.ranges;UIntProgression$Companion;fromClosedRange;(int,int,int);generated", - "kotlin.ranges;UIntProgression;equals;(Object);generated", - "kotlin.ranges;UIntProgression;getFirst;();generated", - "kotlin.ranges;UIntProgression;getLast;();generated", - "kotlin.ranges;UIntProgression;getStep;();generated", - "kotlin.ranges;UIntProgression;hashCode;();generated", - "kotlin.ranges;UIntProgression;isEmpty;();generated", - "kotlin.ranges;UIntProgression;toString;();generated", - "kotlin.ranges;UIntRange;UIntRange;(int,int);generated", - "kotlin.ranges;UIntRange;contains;(int);generated", - "kotlin.ranges;UIntRange;equals;(Object);generated", - "kotlin.ranges;UIntRange;hashCode;();generated", - "kotlin.ranges;UIntRange;toString;();generated", - "kotlin.ranges;ULongProgression$Companion;fromClosedRange;(long,long,long);generated", - "kotlin.ranges;ULongProgression;equals;(Object);generated", - "kotlin.ranges;ULongProgression;getFirst;();generated", - "kotlin.ranges;ULongProgression;getLast;();generated", - "kotlin.ranges;ULongProgression;getStep;();generated", - "kotlin.ranges;ULongProgression;hashCode;();generated", - "kotlin.ranges;ULongProgression;isEmpty;();generated", - "kotlin.ranges;ULongProgression;toString;();generated", - "kotlin.ranges;ULongRange;ULongRange;(long,long);generated", - "kotlin.ranges;ULongRange;contains;(long);generated", - "kotlin.ranges;ULongRange;equals;(Object);generated", - "kotlin.ranges;ULongRange;hashCode;();generated", - "kotlin.ranges;ULongRange;toString;();generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(byte,byte);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(int,int);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(long,long);generated", - "kotlin.ranges;URangesKt;coerceAtLeast;(short,short);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(byte,byte);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(int,int);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(long,long);generated", - "kotlin.ranges;URangesKt;coerceAtMost;(short,short);generated", - "kotlin.ranges;URangesKt;coerceIn;(byte,byte,byte);generated", - "kotlin.ranges;URangesKt;coerceIn;(int,ClosedRange);generated", - "kotlin.ranges;URangesKt;coerceIn;(int,int,int);generated", - "kotlin.ranges;URangesKt;coerceIn;(long,ClosedRange);generated", - "kotlin.ranges;URangesKt;coerceIn;(long,long,long);generated", - "kotlin.ranges;URangesKt;coerceIn;(short,short,short);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,UInt);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,byte);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,long);generated", - "kotlin.ranges;URangesKt;contains;(UIntRange,short);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,ULong);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,byte);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,int);generated", - "kotlin.ranges;URangesKt;contains;(ULongRange,short);generated", - "kotlin.ranges;URangesKt;downTo;(byte,byte);generated", - "kotlin.ranges;URangesKt;downTo;(int,int);generated", - "kotlin.ranges;URangesKt;downTo;(long,long);generated", - "kotlin.ranges;URangesKt;downTo;(short,short);generated", - "kotlin.ranges;URangesKt;first;(UIntProgression);generated", - "kotlin.ranges;URangesKt;first;(ULongProgression);generated", - "kotlin.ranges;URangesKt;firstOrNull;(UIntProgression);generated", - "kotlin.ranges;URangesKt;firstOrNull;(ULongProgression);generated", - "kotlin.ranges;URangesKt;last;(UIntProgression);generated", - "kotlin.ranges;URangesKt;last;(ULongProgression);generated", - "kotlin.ranges;URangesKt;lastOrNull;(UIntProgression);generated", - "kotlin.ranges;URangesKt;lastOrNull;(ULongProgression);generated", - "kotlin.ranges;URangesKt;random;(UIntRange);generated", - "kotlin.ranges;URangesKt;random;(UIntRange,Random);generated", - "kotlin.ranges;URangesKt;random;(ULongRange);generated", - "kotlin.ranges;URangesKt;random;(ULongRange,Random);generated", - "kotlin.ranges;URangesKt;randomOrNull;(UIntRange);generated", - "kotlin.ranges;URangesKt;randomOrNull;(UIntRange,Random);generated", - "kotlin.ranges;URangesKt;randomOrNull;(ULongRange);generated", - "kotlin.ranges;URangesKt;randomOrNull;(ULongRange,Random);generated", - "kotlin.ranges;URangesKt;rangeUntil;(byte,byte);generated", - "kotlin.ranges;URangesKt;rangeUntil;(int,int);generated", - "kotlin.ranges;URangesKt;rangeUntil;(long,long);generated", - "kotlin.ranges;URangesKt;rangeUntil;(short,short);generated", - "kotlin.ranges;URangesKt;reversed;(UIntProgression);generated", - "kotlin.ranges;URangesKt;reversed;(ULongProgression);generated", - "kotlin.ranges;URangesKt;step;(UIntProgression,int);generated", - "kotlin.ranges;URangesKt;step;(ULongProgression,long);generated", - "kotlin.ranges;URangesKt;until;(byte,byte);generated", - "kotlin.ranges;URangesKt;until;(int,int);generated", - "kotlin.ranges;URangesKt;until;(long,long);generated", - "kotlin.ranges;URangesKt;until;(short,short);generated", - "kotlin.reflect;KAnnotatedElement;getAnnotations;();generated", - "kotlin.reflect;KCallable;call;(Object[]);generated", - "kotlin.reflect;KCallable;callBy;(Map);generated", - "kotlin.reflect;KCallable;getName;();generated", - "kotlin.reflect;KCallable;getParameters;();generated", - "kotlin.reflect;KCallable;getReturnType;();generated", - "kotlin.reflect;KCallable;getTypeParameters;();generated", - "kotlin.reflect;KCallable;getVisibility;();generated", - "kotlin.reflect;KCallable;isAbstract;();generated", - "kotlin.reflect;KCallable;isFinal;();generated", - "kotlin.reflect;KCallable;isOpen;();generated", - "kotlin.reflect;KCallable;isSuspend;();generated", - "kotlin.reflect;KClass;equals;(Object);generated", - "kotlin.reflect;KClass;getConstructors;();generated", - "kotlin.reflect;KClass;getNestedClasses;();generated", - "kotlin.reflect;KClass;getObjectInstance;();generated", - "kotlin.reflect;KClass;getQualifiedName;();generated", - "kotlin.reflect;KClass;getSealedSubclasses;();generated", - "kotlin.reflect;KClass;getSimpleName;();generated", - "kotlin.reflect;KClass;getSupertypes;();generated", - "kotlin.reflect;KClass;getTypeParameters;();generated", - "kotlin.reflect;KClass;getVisibility;();generated", - "kotlin.reflect;KClass;hashCode;();generated", - "kotlin.reflect;KClass;isAbstract;();generated", - "kotlin.reflect;KClass;isCompanion;();generated", - "kotlin.reflect;KClass;isData;();generated", "kotlin.reflect;KClass;isFinal;();generated", - "kotlin.reflect;KClass;isFun;();generated", "kotlin.reflect;KClass;isInner;();generated", - "kotlin.reflect;KClass;isInstance;(Object);generated", - "kotlin.reflect;KClass;isOpen;();generated", "kotlin.reflect;KClass;isSealed;();generated", - "kotlin.reflect;KClass;isValue;();generated", - "kotlin.reflect;KDeclarationContainer;getMembers;();generated", - "kotlin.reflect;KFunction;isExternal;();generated", - "kotlin.reflect;KFunction;isInfix;();generated", - "kotlin.reflect;KFunction;isInline;();generated", - "kotlin.reflect;KFunction;isOperator;();generated", - "kotlin.reflect;KMutableProperty0;set;(Object);generated", - "kotlin.reflect;KMutableProperty1;set;(Object,Object);generated", - "kotlin.reflect;KMutableProperty2;set;(Object,Object,Object);generated", - "kotlin.reflect;KMutableProperty;getSetter;();generated", - "kotlin.reflect;KParameter$Kind;valueOf;(String);generated", - "kotlin.reflect;KParameter$Kind;values;();generated", - "kotlin.reflect;KParameter;getIndex;();generated", - "kotlin.reflect;KParameter;getKind;();generated", - "kotlin.reflect;KParameter;getName;();generated", - "kotlin.reflect;KParameter;getType;();generated", - "kotlin.reflect;KParameter;isOptional;();generated", - "kotlin.reflect;KParameter;isVararg;();generated", - "kotlin.reflect;KProperty$Accessor;getProperty;();generated", - "kotlin.reflect;KProperty0;get;();generated", - "kotlin.reflect;KProperty0;getDelegate;();generated", - "kotlin.reflect;KProperty1;get;(Object);generated", - "kotlin.reflect;KProperty1;getDelegate;(Object);generated", - "kotlin.reflect;KProperty2;get;(Object,Object);generated", - "kotlin.reflect;KProperty2;getDelegate;(Object,Object);generated", - "kotlin.reflect;KProperty;getGetter;();generated", - "kotlin.reflect;KProperty;isConst;();generated", - "kotlin.reflect;KProperty;isLateinit;();generated", - "kotlin.reflect;KType;getArguments;();generated", - "kotlin.reflect;KType;getClassifier;();generated", - "kotlin.reflect;KType;isMarkedNullable;();generated", - "kotlin.reflect;KTypeParameter;getName;();generated", - "kotlin.reflect;KTypeParameter;getUpperBounds;();generated", - "kotlin.reflect;KTypeParameter;getVariance;();generated", - "kotlin.reflect;KTypeParameter;isReified;();generated", - "kotlin.reflect;KTypeProjection$Companion;getSTAR;();generated", - "kotlin.reflect;KTypeProjection;component1;();generated", - "kotlin.reflect;KTypeProjection;equals;(Object);generated", - "kotlin.reflect;KTypeProjection;getVariance;();generated", - "kotlin.reflect;KTypeProjection;hashCode;();generated", - "kotlin.reflect;KVariance;valueOf;(String);generated", - "kotlin.reflect;KVariance;values;();generated", - "kotlin.reflect;KVisibility;valueOf;(String);generated", - "kotlin.reflect;KVisibility;values;();generated", - "kotlin.reflect;TypeOfKt;typeOf;();generated", - "kotlin.sequences;Sequence;iterator;();generated", - "kotlin.sequences;SequenceScope;yield;(Object);generated", - "kotlin.sequences;SequenceScope;yieldAll;(Iterable);generated", - "kotlin.sequences;SequenceScope;yieldAll;(Iterator);generated", - "kotlin.sequences;SequencesKt;Sequence;(Function0);generated", - "kotlin.sequences;SequencesKt;all;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;any;(Sequence);generated", - "kotlin.sequences;SequencesKt;any;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;asIterable;(Sequence);generated", - "kotlin.sequences;SequencesKt;asSequence;(Enumeration);generated", - "kotlin.sequences;SequencesKt;asSequence;(Iterator);generated", - "kotlin.sequences;SequencesKt;associate;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;associateBy;(Sequence,Function1,Function1);generated", - "kotlin.sequences;SequencesKt;averageOfByte;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfDouble;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfFloat;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfInt;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfLong;(Sequence);generated", - "kotlin.sequences;SequencesKt;averageOfShort;(Sequence);generated", - "kotlin.sequences;SequencesKt;chunked;(Sequence,int);generated", - "kotlin.sequences;SequencesKt;contains;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;count;(Sequence);generated", - "kotlin.sequences;SequencesKt;count;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;emptySequence;();generated", - "kotlin.sequences;SequencesKt;filterIndexed;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;flatMapIndexedIterable;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;flatMapIndexedSequence;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;forEach;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;forEachIndexed;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;groupBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;groupBy;(Sequence,Function1,Function1);generated", - "kotlin.sequences;SequencesKt;groupingBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;ifEmpty;(Sequence,Function0);generated", - "kotlin.sequences;SequencesKt;indexOf;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;indexOfFirst;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;indexOfLast;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;iterator;(SuspendFunction1);generated", - "kotlin.sequences;SequencesKt;lastIndexOf;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;max;(Sequence);generated", - "kotlin.sequences;SequencesKt;maxOf;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;maxOfOrNull;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;maxOrNull;(Sequence);generated", - "kotlin.sequences;SequencesKt;maxOrThrow;(Sequence);generated", - "kotlin.sequences;SequencesKt;min;(Sequence);generated", - "kotlin.sequences;SequencesKt;minOf;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;minOfOrNull;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;minOrNull;(Sequence);generated", - "kotlin.sequences;SequencesKt;minOrThrow;(Sequence);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Iterable);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;minus;(Sequence,Sequence);generated", - "kotlin.sequences;SequencesKt;minusElement;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;none;(Sequence);generated", - "kotlin.sequences;SequencesKt;none;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Iterable);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Object[]);generated", - "kotlin.sequences;SequencesKt;plus;(Sequence,Sequence);generated", - "kotlin.sequences;SequencesKt;plusElement;(Sequence,Object);generated", - "kotlin.sequences;SequencesKt;runningFold;(Sequence,Object,Function2);generated", - "kotlin.sequences;SequencesKt;runningFoldIndexed;(Sequence,Object,Function3);generated", - "kotlin.sequences;SequencesKt;runningReduce;(Sequence,Function2);generated", - "kotlin.sequences;SequencesKt;runningReduceIndexed;(Sequence,Function3);generated", - "kotlin.sequences;SequencesKt;scan;(Sequence,Object,Function2);generated", - "kotlin.sequences;SequencesKt;scanIndexed;(Sequence,Object,Function3);generated", - "kotlin.sequences;SequencesKt;sequence;(SuspendFunction1);generated", - "kotlin.sequences;SequencesKt;sequenceOf;(Object[]);generated", - "kotlin.sequences;SequencesKt;shuffled;(Sequence);generated", - "kotlin.sequences;SequencesKt;shuffled;(Sequence,Random);generated", - "kotlin.sequences;SequencesKt;sorted;(Sequence);generated", - "kotlin.sequences;SequencesKt;sortedBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sortedByDescending;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sortedDescending;(Sequence);generated", - "kotlin.sequences;SequencesKt;sortedWith;(Sequence,Comparator);generated", - "kotlin.sequences;SequencesKt;sumBy;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumByDouble;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfBigDecimal;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfBigInteger;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfByte;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfDouble;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfDouble;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfFloat;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfInt;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfInt;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfLong;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfLong;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfShort;(Sequence);generated", - "kotlin.sequences;SequencesKt;sumOfUInt;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;sumOfULong;(Sequence,Function1);generated", - "kotlin.sequences;SequencesKt;windowed;(Sequence,int,int,boolean);generated", - "kotlin.sequences;SequencesKt;zipWithNext;(Sequence);generated", - "kotlin.sequences;SequencesKt;zipWithNext;(Sequence,Function2);generated", - "kotlin.sequences;USequencesKt;sumOfUByte;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfUInt;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfULong;(Sequence);generated", - "kotlin.sequences;USequencesKt;sumOfUShort;(Sequence);generated", - "kotlin.system;ProcessKt;exitProcess;(int);generated", - "kotlin.system;TimingKt;measureNanoTime;(Function0);generated", - "kotlin.system;TimingKt;measureTimeMillis;(Function0);generated", - "kotlin.text;Appendable;append;(CharSequence);generated", - "kotlin.text;Appendable;append;(CharSequence,int,int);generated", - "kotlin.text;Appendable;append;(char);generated", - "kotlin.text;CharCategory$Companion;valueOf;(int);generated", - "kotlin.text;CharCategory;contains;(char);generated", - "kotlin.text;CharCategory;getCode;();generated", - "kotlin.text;CharCategory;getValue;();generated", - "kotlin.text;CharCategory;valueOf;(String);generated", - "kotlin.text;CharCategory;values;();generated", - "kotlin.text;CharDirectionality$Companion;valueOf;(int);generated", - "kotlin.text;CharDirectionality;getValue;();generated", - "kotlin.text;CharDirectionality;valueOf;(String);generated", - "kotlin.text;CharDirectionality;values;();generated", - "kotlin.text;CharacterCodingException;CharacterCodingException;();generated", - "kotlin.text;CharsKt;digitToChar;(int);generated", - "kotlin.text;CharsKt;digitToChar;(int,int);generated", - "kotlin.text;CharsKt;digitToInt;(char);generated", - "kotlin.text;CharsKt;digitToInt;(char,int);generated", - "kotlin.text;CharsKt;digitToIntOrNull;(char);generated", - "kotlin.text;CharsKt;digitToIntOrNull;(char,int);generated", - "kotlin.text;CharsKt;equals;(char,char,boolean);generated", - "kotlin.text;CharsKt;getCategory;(char);generated", - "kotlin.text;CharsKt;getDirectionality;(char);generated", - "kotlin.text;CharsKt;isDefined;(char);generated", - "kotlin.text;CharsKt;isDigit;(char);generated", - "kotlin.text;CharsKt;isHighSurrogate;(char);generated", - "kotlin.text;CharsKt;isISOControl;(char);generated", - "kotlin.text;CharsKt;isIdentifierIgnorable;(char);generated", - "kotlin.text;CharsKt;isJavaIdentifierPart;(char);generated", - "kotlin.text;CharsKt;isJavaIdentifierStart;(char);generated", - "kotlin.text;CharsKt;isLetter;(char);generated", - "kotlin.text;CharsKt;isLetterOrDigit;(char);generated", - "kotlin.text;CharsKt;isLowSurrogate;(char);generated", - "kotlin.text;CharsKt;isLowerCase;(char);generated", - "kotlin.text;CharsKt;isSurrogate;(char);generated", - "kotlin.text;CharsKt;isTitleCase;(char);generated", - "kotlin.text;CharsKt;isUpperCase;(char);generated", - "kotlin.text;CharsKt;isWhitespace;(char);generated", - "kotlin.text;CharsKt;lowercase;(char);generated", - "kotlin.text;CharsKt;lowercase;(char,Locale);generated", - "kotlin.text;CharsKt;lowercaseChar;(char);generated", - "kotlin.text;CharsKt;titlecase;(char);generated", - "kotlin.text;CharsKt;titlecase;(char,Locale);generated", - "kotlin.text;CharsKt;titlecaseChar;(char);generated", - "kotlin.text;CharsKt;toLowerCase;(char);generated", - "kotlin.text;CharsKt;toTitleCase;(char);generated", - "kotlin.text;CharsKt;toUpperCase;(char);generated", - "kotlin.text;CharsKt;uppercase;(char);generated", - "kotlin.text;CharsKt;uppercase;(char,Locale);generated", - "kotlin.text;CharsKt;uppercaseChar;(char);generated", - "kotlin.text;Charsets;UTF32;();generated", "kotlin.text;Charsets;UTF32_BE;();generated", - "kotlin.text;Charsets;UTF32_LE;();generated", - "kotlin.text;Charsets;getISO_8859_1;();generated", - "kotlin.text;Charsets;getUS_ASCII;();generated", - "kotlin.text;Charsets;getUTF_16;();generated", - "kotlin.text;Charsets;getUTF_16BE;();generated", - "kotlin.text;Charsets;getUTF_16LE;();generated", - "kotlin.text;Charsets;getUTF_8;();generated", - "kotlin.text;CharsetsKt;charset;(String);generated", - "kotlin.text;FlagEnum;getMask;();generated", "kotlin.text;FlagEnum;getValue;();generated", - "kotlin.text;MatchGroup;equals;(Object);generated", - "kotlin.text;MatchGroup;hashCode;();generated", - "kotlin.text;MatchGroupCollection;get;(int);generated", - "kotlin.text;MatchNamedGroupCollection;get;(String);generated", - "kotlin.text;MatchResult;getGroupValues;();generated", - "kotlin.text;MatchResult;getGroups;();generated", - "kotlin.text;MatchResult;getRange;();generated", - "kotlin.text;MatchResult;getValue;();generated", - "kotlin.text;MatchResult;next;();generated", - "kotlin.text;Regex$Companion;escapeReplacement;(String);generated", - "kotlin.text;Regex$Companion;fromLiteral;(String);generated", - "kotlin.text;Regex;Regex;(String);generated", - "kotlin.text;Regex;Regex;(String,RegexOption);generated", - "kotlin.text;Regex;Regex;(String,Set);generated", - "kotlin.text;Regex;containsMatchIn;(CharSequence);generated", - "kotlin.text;Regex;findAll;(CharSequence,int);generated", - "kotlin.text;Regex;getPattern;();generated", - "kotlin.text;Regex;matchAt;(CharSequence,int);generated", - "kotlin.text;Regex;matches;(CharSequence);generated", - "kotlin.text;Regex;matchesAt;(CharSequence,int);generated", - "kotlin.text;Regex;split;(CharSequence,int);generated", - "kotlin.text;Regex;splitToSequence;(CharSequence,int);generated", - "kotlin.text;Regex;toString;();generated", - "kotlin.text;RegexOption;valueOf;(String);generated", - "kotlin.text;RegexOption;values;();generated", - "kotlin.text;StringBuilder;StringBuilder;();generated", - "kotlin.text;StringBuilder;StringBuilder;(CharSequence);generated", - "kotlin.text;StringBuilder;StringBuilder;(String);generated", - "kotlin.text;StringBuilder;StringBuilder;(int);generated", - "kotlin.text;StringBuilder;append;(Object);generated", - "kotlin.text;StringBuilder;append;(String);generated", - "kotlin.text;StringBuilder;append;(boolean);generated", - "kotlin.text;StringBuilder;append;(char[]);generated", - "kotlin.text;StringBuilder;capacity;();generated", - "kotlin.text;StringBuilder;ensureCapacity;(int);generated", - "kotlin.text;StringBuilder;get;(int);generated", - "kotlin.text;StringBuilder;indexOf;(String);generated", - "kotlin.text;StringBuilder;indexOf;(String,int);generated", - "kotlin.text;StringBuilder;insert;(int,CharSequence);generated", - "kotlin.text;StringBuilder;insert;(int,Object);generated", - "kotlin.text;StringBuilder;insert;(int,String);generated", - "kotlin.text;StringBuilder;insert;(int,boolean);generated", - "kotlin.text;StringBuilder;insert;(int,char);generated", - "kotlin.text;StringBuilder;insert;(int,char[]);generated", - "kotlin.text;StringBuilder;lastIndexOf;(String);generated", - "kotlin.text;StringBuilder;lastIndexOf;(String,int);generated", - "kotlin.text;StringBuilder;reverse;();generated", - "kotlin.text;StringBuilder;setLength;(int);generated", - "kotlin.text;StringBuilder;substring;(int);generated", - "kotlin.text;StringBuilder;substring;(int,int);generated", - "kotlin.text;StringBuilder;trimToSize;();generated", - "kotlin.text;StringsKt;String;(int[],int,int);generated", - "kotlin.text;StringsKt;all;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;any;(CharSequence);generated", - "kotlin.text;StringsKt;any;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;asIterable;(CharSequence);generated", - "kotlin.text;StringsKt;asSequence;(CharSequence);generated", - "kotlin.text;StringsKt;associate;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;associateBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;associateBy;(CharSequence,Function1,Function1);generated", - "kotlin.text;StringsKt;associateWith;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;buildString;(Function1);generated", - "kotlin.text;StringsKt;buildString;(int,Function1);generated", - "kotlin.text;StringsKt;chunked;(CharSequence,int);generated", - "kotlin.text;StringsKt;chunked;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;chunkedSequence;(CharSequence,int);generated", - "kotlin.text;StringsKt;chunkedSequence;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;codePointAt;(String,int);generated", - "kotlin.text;StringsKt;codePointBefore;(String,int);generated", - "kotlin.text;StringsKt;codePointCount;(String,int,int);generated", - "kotlin.text;StringsKt;commonPrefixWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;commonSuffixWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;compareTo;(String,String,boolean);generated", - "kotlin.text;StringsKt;contains;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;contains;(CharSequence,Regex);generated", - "kotlin.text;StringsKt;contains;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;contentEquals;(CharSequence,CharSequence);generated", - "kotlin.text;StringsKt;contentEquals;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;contentEquals;(String,CharSequence);generated", - "kotlin.text;StringsKt;contentEquals;(String,StringBuffer);generated", - "kotlin.text;StringsKt;count;(CharSequence);generated", - "kotlin.text;StringsKt;count;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;deleteAt;(StringBuilder,int);generated", - "kotlin.text;StringsKt;deleteRange;(StringBuilder,int,int);generated", - "kotlin.text;StringsKt;elementAt;(CharSequence,int);generated", - "kotlin.text;StringsKt;elementAtOrElse;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;elementAtOrNull;(CharSequence,int);generated", - "kotlin.text;StringsKt;endsWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;endsWith;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;endsWith;(String,String,boolean);generated", - "kotlin.text;StringsKt;equals;(String,String,boolean);generated", - "kotlin.text;StringsKt;filter;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;filter;(String,Function1);generated", - "kotlin.text;StringsKt;filterIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;filterIndexed;(String,Function2);generated", - "kotlin.text;StringsKt;filterNot;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;filterNot;(String,Function1);generated", - "kotlin.text;StringsKt;find;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;findLast;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;first;(CharSequence);generated", - "kotlin.text;StringsKt;first;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstNotNullOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstNotNullOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;firstOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;firstOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;flatMap;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;flatMapIndexedIterable;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;forEach;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;forEachIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;getCASE_INSENSITIVE_ORDER;(StringCompanionObject);generated", - "kotlin.text;StringsKt;getIndices;(CharSequence);generated", - "kotlin.text;StringsKt;getLastIndex;(CharSequence);generated", - "kotlin.text;StringsKt;getOrElse;(CharSequence,int,Function1);generated", - "kotlin.text;StringsKt;getOrNull;(CharSequence,int);generated", - "kotlin.text;StringsKt;groupBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;groupBy;(CharSequence,Function1,Function1);generated", - "kotlin.text;StringsKt;groupingBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;hasSurrogatePairAt;(CharSequence,int);generated", - "kotlin.text;StringsKt;indexOf;(CharSequence,String,int,boolean);generated", - "kotlin.text;StringsKt;indexOf;(CharSequence,char,int,boolean);generated", - "kotlin.text;StringsKt;indexOfAny;(CharSequence,Collection,int,boolean);generated", - "kotlin.text;StringsKt;indexOfAny;(CharSequence,char[],int,boolean);generated", - "kotlin.text;StringsKt;indexOfFirst;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;indexOfLast;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;isBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;isNotBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isNotEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;isNullOrBlank;(CharSequence);generated", - "kotlin.text;StringsKt;isNullOrEmpty;(CharSequence);generated", - "kotlin.text;StringsKt;iterator;(CharSequence);generated", - "kotlin.text;StringsKt;last;(CharSequence);generated", - "kotlin.text;StringsKt;last;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;lastIndexOf;(CharSequence,String,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOf;(CharSequence,char,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOfAny;(CharSequence,Collection,int,boolean);generated", - "kotlin.text;StringsKt;lastIndexOfAny;(CharSequence,char[],int,boolean);generated", - "kotlin.text;StringsKt;lastOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;lastOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;map;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;mapIndexed;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;mapIndexedNotNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;mapNotNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;matches;(CharSequence,Regex);generated", - "kotlin.text;StringsKt;max;(CharSequence);generated", - "kotlin.text;StringsKt;maxBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxByOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxByOrThrow;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;maxOfWith;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;maxOfWithOrNull;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;maxOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;maxOrThrow;(CharSequence);generated", - "kotlin.text;StringsKt;maxWith;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;maxWithOrNull;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;maxWithOrThrow;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;min;(CharSequence);generated", - "kotlin.text;StringsKt;minBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minByOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minByOrThrow;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOf;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOfOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;minOfWith;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;minOfWithOrNull;(CharSequence,Comparator,Function1);generated", - "kotlin.text;StringsKt;minOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;minOrThrow;(CharSequence);generated", - "kotlin.text;StringsKt;minWith;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;minWithOrNull;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;minWithOrThrow;(CharSequence,Comparator);generated", - "kotlin.text;StringsKt;none;(CharSequence);generated", - "kotlin.text;StringsKt;none;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;offsetByCodePoints;(String,int,int);generated", - "kotlin.text;StringsKt;padEnd;(String,int,char);generated", - "kotlin.text;StringsKt;padStart;(String,int,char);generated", - "kotlin.text;StringsKt;partition;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;partition;(String,Function1);generated", - "kotlin.text;StringsKt;random;(CharSequence);generated", - "kotlin.text;StringsKt;random;(CharSequence,Random);generated", - "kotlin.text;StringsKt;randomOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;randomOrNull;(CharSequence,Random);generated", - "kotlin.text;StringsKt;reduce;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceIndexedOrNull;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceOrNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceRight;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;reduceRightIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceRightIndexedOrNull;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;reduceRightOrNull;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;regionMatches;(CharSequence,int,CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;regionMatches;(String,int,String,int,int,boolean);generated", - "kotlin.text;StringsKt;removeRange;(String,IntRange);generated", - "kotlin.text;StringsKt;removeRange;(String,int,int);generated", - "kotlin.text;StringsKt;replace;(String,String,String,boolean);generated", - "kotlin.text;StringsKt;replaceIndent;(String,String);generated", - "kotlin.text;StringsKt;replaceIndentByMargin;(String,String,String);generated", - "kotlin.text;StringsKt;replaceRange;(String,IntRange,CharSequence);generated", - "kotlin.text;StringsKt;replaceRange;(String,int,int,CharSequence);generated", - "kotlin.text;StringsKt;reversed;(String);generated", - "kotlin.text;StringsKt;runningReduce;(CharSequence,Function2);generated", - "kotlin.text;StringsKt;runningReduceIndexed;(CharSequence,Function3);generated", - "kotlin.text;StringsKt;set;(StringBuilder,int,char);generated", - "kotlin.text;StringsKt;single;(CharSequence);generated", - "kotlin.text;StringsKt;single;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;singleOrNull;(CharSequence);generated", - "kotlin.text;StringsKt;singleOrNull;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;slice;(CharSequence,Iterable);generated", - "kotlin.text;StringsKt;slice;(String,Iterable);generated", - "kotlin.text;StringsKt;split;(CharSequence,Regex,int);generated", - "kotlin.text;StringsKt;split;(CharSequence,String[],boolean,int);generated", - "kotlin.text;StringsKt;split;(CharSequence,char[],boolean,int);generated", - "kotlin.text;StringsKt;splitToSequence;(CharSequence,Regex,int);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,CharSequence,boolean);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,CharSequence,int,boolean);generated", - "kotlin.text;StringsKt;startsWith;(CharSequence,char,boolean);generated", - "kotlin.text;StringsKt;startsWith;(String,String,boolean);generated", - "kotlin.text;StringsKt;startsWith;(String,String,int,boolean);generated", - "kotlin.text;StringsKt;substring;(CharSequence,IntRange);generated", - "kotlin.text;StringsKt;substring;(CharSequence,int,int);generated", - "kotlin.text;StringsKt;sumBy;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumByDouble;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfBigDecimal;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfBigInteger;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfDouble;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfInt;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfLong;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfUInt;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;sumOfULong;(CharSequence,Function1);generated", - "kotlin.text;StringsKt;toBigDecimal;(String);generated", - "kotlin.text;StringsKt;toBigDecimal;(String,MathContext);generated", - "kotlin.text;StringsKt;toBigDecimalOrNull;(String);generated", - "kotlin.text;StringsKt;toBigDecimalOrNull;(String,MathContext);generated", - "kotlin.text;StringsKt;toBigInteger;(String);generated", - "kotlin.text;StringsKt;toBigInteger;(String,int);generated", - "kotlin.text;StringsKt;toBigIntegerOrNull;(String);generated", - "kotlin.text;StringsKt;toBigIntegerOrNull;(String,int);generated", - "kotlin.text;StringsKt;toBoolean;(String);generated", - "kotlin.text;StringsKt;toBooleanNullable;(String);generated", - "kotlin.text;StringsKt;toBooleanStrict;(String);generated", - "kotlin.text;StringsKt;toBooleanStrictOrNull;(String);generated", - "kotlin.text;StringsKt;toByte;(String);generated", - "kotlin.text;StringsKt;toByte;(String,int);generated", - "kotlin.text;StringsKt;toByteOrNull;(String);generated", - "kotlin.text;StringsKt;toByteOrNull;(String,int);generated", - "kotlin.text;StringsKt;toDouble;(String);generated", - "kotlin.text;StringsKt;toDoubleOrNull;(String);generated", - "kotlin.text;StringsKt;toFloat;(String);generated", - "kotlin.text;StringsKt;toFloatOrNull;(String);generated", - "kotlin.text;StringsKt;toHashSet;(CharSequence);generated", - "kotlin.text;StringsKt;toInt;(String);generated", - "kotlin.text;StringsKt;toInt;(String,int);generated", - "kotlin.text;StringsKt;toIntOrNull;(String);generated", - "kotlin.text;StringsKt;toIntOrNull;(String,int);generated", - "kotlin.text;StringsKt;toList;(CharSequence);generated", - "kotlin.text;StringsKt;toLong;(String);generated", - "kotlin.text;StringsKt;toLong;(String,int);generated", - "kotlin.text;StringsKt;toLongOrNull;(String);generated", - "kotlin.text;StringsKt;toLongOrNull;(String,int);generated", - "kotlin.text;StringsKt;toMutableList;(CharSequence);generated", - "kotlin.text;StringsKt;toPattern;(String,int);generated", - "kotlin.text;StringsKt;toRegex;(String);generated", - "kotlin.text;StringsKt;toRegex;(String,RegexOption);generated", - "kotlin.text;StringsKt;toRegex;(String,Set);generated", - "kotlin.text;StringsKt;toSet;(CharSequence);generated", - "kotlin.text;StringsKt;toShort;(String);generated", - "kotlin.text;StringsKt;toShort;(String,int);generated", - "kotlin.text;StringsKt;toShortOrNull;(String);generated", - "kotlin.text;StringsKt;toShortOrNull;(String,int);generated", - "kotlin.text;StringsKt;toSortedSet;(CharSequence);generated", - "kotlin.text;StringsKt;toString;(byte,int);generated", - "kotlin.text;StringsKt;toString;(int,int);generated", - "kotlin.text;StringsKt;toString;(long,int);generated", - "kotlin.text;StringsKt;toString;(short,int);generated", - "kotlin.text;StringsKt;trim;(String);generated", - "kotlin.text;StringsKt;trim;(String,Function1);generated", - "kotlin.text;StringsKt;trim;(String,char[]);generated", - "kotlin.text;StringsKt;trimEnd;(String);generated", - "kotlin.text;StringsKt;trimEnd;(String,Function1);generated", - "kotlin.text;StringsKt;trimEnd;(String,char[]);generated", - "kotlin.text;StringsKt;trimIndent;(String);generated", - "kotlin.text;StringsKt;trimMargin;(String,String);generated", - "kotlin.text;StringsKt;trimStart;(String);generated", - "kotlin.text;StringsKt;trimStart;(String,Function1);generated", - "kotlin.text;StringsKt;trimStart;(String,char[]);generated", - "kotlin.text;StringsKt;windowed;(CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;windowed;(CharSequence,int,int,boolean,Function1);generated", - "kotlin.text;StringsKt;windowedSequence;(CharSequence,int,int,boolean);generated", - "kotlin.text;StringsKt;windowedSequence;(CharSequence,int,int,boolean,Function1);generated", - "kotlin.text;StringsKt;withIndex;(CharSequence);generated", - "kotlin.text;StringsKt;zip;(CharSequence,CharSequence);generated", - "kotlin.text;StringsKt;zip;(CharSequence,CharSequence,Function2);generated", - "kotlin.text;StringsKt;zipWithNext;(CharSequence);generated", - "kotlin.text;StringsKt;zipWithNext;(CharSequence,Function2);generated", - "kotlin.text;TextHKt;String;(char[]);generated", - "kotlin.text;TextHKt;String;(char[],int,int);generated", - "kotlin.text;TextHKt;compareTo;(String,String,boolean);generated", - "kotlin.text;TextHKt;concatToString;(char[]);generated", - "kotlin.text;TextHKt;concatToString;(char[],int,int);generated", - "kotlin.text;TextHKt;decodeToString;(byte[]);generated", - "kotlin.text;TextHKt;decodeToString;(byte[],int,int,boolean);generated", - "kotlin.text;TextHKt;encodeToByteArray;(String);generated", - "kotlin.text;TextHKt;encodeToByteArray;(String,int,int,boolean);generated", - "kotlin.text;TextHKt;endsWith;(String,String,boolean);generated", - "kotlin.text;TextHKt;equals;(String,String,boolean);generated", - "kotlin.text;TextHKt;getCASE_INSENSITIVE_ORDER;(StringCompanionObject);generated", - "kotlin.text;TextHKt;isBlank;(CharSequence);generated", - "kotlin.text;TextHKt;isHighSurrogate;(char);generated", - "kotlin.text;TextHKt;isLowSurrogate;(char);generated", - "kotlin.text;TextHKt;regionMatches;(CharSequence,int,CharSequence,int,int,boolean);generated", - "kotlin.text;TextHKt;repeat;(CharSequence,int);generated", - "kotlin.text;TextHKt;replace;(String,String,String,boolean);generated", - "kotlin.text;TextHKt;replace;(String,char,char,boolean);generated", - "kotlin.text;TextHKt;replaceFirst;(String,String,String,boolean);generated", - "kotlin.text;TextHKt;replaceFirst;(String,char,char,boolean);generated", - "kotlin.text;TextHKt;startsWith;(String,String,boolean);generated", - "kotlin.text;TextHKt;startsWith;(String,String,int,boolean);generated", - "kotlin.text;TextHKt;substring;(String,int);generated", - "kotlin.text;TextHKt;substring;(String,int,int);generated", - "kotlin.text;TextHKt;toBoolean;(String);generated", - "kotlin.text;TextHKt;toByte;(String);generated", - "kotlin.text;TextHKt;toByte;(String,int);generated", - "kotlin.text;TextHKt;toCharArray;(String);generated", - "kotlin.text;TextHKt;toCharArray;(String,int,int);generated", - "kotlin.text;TextHKt;toDouble;(String);generated", - "kotlin.text;TextHKt;toDoubleOrNull;(String);generated", - "kotlin.text;TextHKt;toFloat;(String);generated", - "kotlin.text;TextHKt;toFloatOrNull;(String);generated", - "kotlin.text;TextHKt;toInt;(String);generated", - "kotlin.text;TextHKt;toInt;(String,int);generated", - "kotlin.text;TextHKt;toLong;(String);generated", - "kotlin.text;TextHKt;toLong;(String,int);generated", - "kotlin.text;TextHKt;toShort;(String);generated", - "kotlin.text;TextHKt;toShort;(String,int);generated", - "kotlin.text;TextHKt;toString;(byte,int);generated", - "kotlin.text;TextHKt;toString;(int,int);generated", - "kotlin.text;TextHKt;toString;(long,int);generated", - "kotlin.text;TextHKt;toString;(short,int);generated", - "kotlin.text;Typography;getAlmostEqual;();generated", - "kotlin.text;Typography;getAmp;();generated", - "kotlin.text;Typography;getBullet;();generated", - "kotlin.text;Typography;getCent;();generated", - "kotlin.text;Typography;getCopyright;();generated", - "kotlin.text;Typography;getDagger;();generated", - "kotlin.text;Typography;getDegree;();generated", - "kotlin.text;Typography;getDollar;();generated", - "kotlin.text;Typography;getDoubleDagger;();generated", - "kotlin.text;Typography;getDoublePrime;();generated", - "kotlin.text;Typography;getEllipsis;();generated", - "kotlin.text;Typography;getEuro;();generated", - "kotlin.text;Typography;getGreater;();generated", - "kotlin.text;Typography;getGreaterOrEqual;();generated", - "kotlin.text;Typography;getHalf;();generated", - "kotlin.text;Typography;getLeftDoubleQuote;();generated", - "kotlin.text;Typography;getLeftGuillemet;();generated", - "kotlin.text;Typography;getLeftGuillemete;();generated", - "kotlin.text;Typography;getLeftSingleQuote;();generated", - "kotlin.text;Typography;getLess;();generated", - "kotlin.text;Typography;getLessOrEqual;();generated", - "kotlin.text;Typography;getLowDoubleQuote;();generated", - "kotlin.text;Typography;getLowSingleQuote;();generated", - "kotlin.text;Typography;getMdash;();generated", - "kotlin.text;Typography;getMiddleDot;();generated", - "kotlin.text;Typography;getNbsp;();generated", - "kotlin.text;Typography;getNdash;();generated", - "kotlin.text;Typography;getNotEqual;();generated", - "kotlin.text;Typography;getParagraph;();generated", - "kotlin.text;Typography;getPlusMinus;();generated", - "kotlin.text;Typography;getPound;();generated", - "kotlin.text;Typography;getPrime;();generated", - "kotlin.text;Typography;getQuote;();generated", - "kotlin.text;Typography;getRegistered;();generated", - "kotlin.text;Typography;getRightDoubleQuote;();generated", - "kotlin.text;Typography;getRightGuillemet;();generated", - "kotlin.text;Typography;getRightGuillemete;();generated", - "kotlin.text;Typography;getRightSingleQuote;();generated", - "kotlin.text;Typography;getSection;();generated", - "kotlin.text;Typography;getTimes;();generated", "kotlin.text;Typography;getTm;();generated", - "kotlin.text;UStringsKt;toString;(byte,int);generated", - "kotlin.text;UStringsKt;toString;(int,int);generated", - "kotlin.text;UStringsKt;toString;(long,int);generated", - "kotlin.text;UStringsKt;toString;(short,int);generated", - "kotlin.text;UStringsKt;toUByte;(String);generated", - "kotlin.text;UStringsKt;toUByte;(String,int);generated", - "kotlin.text;UStringsKt;toUByteOrNull;(String);generated", - "kotlin.text;UStringsKt;toUByteOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toUInt;(String);generated", - "kotlin.text;UStringsKt;toUInt;(String,int);generated", - "kotlin.text;UStringsKt;toUIntOrNull;(String);generated", - "kotlin.text;UStringsKt;toUIntOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toULong;(String);generated", - "kotlin.text;UStringsKt;toULong;(String,int);generated", - "kotlin.text;UStringsKt;toULongOrNull;(String);generated", - "kotlin.text;UStringsKt;toULongOrNull;(String,int);generated", - "kotlin.text;UStringsKt;toUShort;(String);generated", - "kotlin.text;UStringsKt;toUShort;(String,int);generated", - "kotlin.text;UStringsKt;toUShortOrNull;(String);generated", - "kotlin.text;UStringsKt;toUShortOrNull;(String,int);generated", - "kotlin.time;AbstractDoubleTimeSource;AbstractDoubleTimeSource;(DurationUnit);generated", - "kotlin.time;AbstractLongTimeSource;AbstractLongTimeSource;(DurationUnit);generated", - "kotlin.time;Duration$Companion;convert;(double,DurationUnit,DurationUnit);generated", - "kotlin.time;Duration$Companion;days;(double);generated", - "kotlin.time;Duration$Companion;days;(int);generated", - "kotlin.time;Duration$Companion;days;(long);generated", - "kotlin.time;Duration$Companion;getDays;(double);generated", - "kotlin.time;Duration$Companion;getDays;(int);generated", - "kotlin.time;Duration$Companion;getDays;(long);generated", - "kotlin.time;Duration$Companion;getHours;(double);generated", - "kotlin.time;Duration$Companion;getHours;(int);generated", - "kotlin.time;Duration$Companion;getHours;(long);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(double);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(int);generated", - "kotlin.time;Duration$Companion;getMicroseconds;(long);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(double);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(int);generated", - "kotlin.time;Duration$Companion;getMilliseconds;(long);generated", - "kotlin.time;Duration$Companion;getMinutes;(double);generated", - "kotlin.time;Duration$Companion;getMinutes;(int);generated", - "kotlin.time;Duration$Companion;getMinutes;(long);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(double);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(int);generated", - "kotlin.time;Duration$Companion;getNanoseconds;(long);generated", - "kotlin.time;Duration$Companion;getSeconds;(double);generated", - "kotlin.time;Duration$Companion;getSeconds;(int);generated", - "kotlin.time;Duration$Companion;getSeconds;(long);generated", - "kotlin.time;Duration$Companion;hours;(double);generated", - "kotlin.time;Duration$Companion;hours;(int);generated", - "kotlin.time;Duration$Companion;hours;(long);generated", - "kotlin.time;Duration$Companion;microseconds;(double);generated", - "kotlin.time;Duration$Companion;microseconds;(int);generated", - "kotlin.time;Duration$Companion;microseconds;(long);generated", - "kotlin.time;Duration$Companion;milliseconds;(double);generated", - "kotlin.time;Duration$Companion;milliseconds;(int);generated", - "kotlin.time;Duration$Companion;milliseconds;(long);generated", - "kotlin.time;Duration$Companion;minutes;(double);generated", - "kotlin.time;Duration$Companion;minutes;(int);generated", - "kotlin.time;Duration$Companion;minutes;(long);generated", - "kotlin.time;Duration$Companion;nanoseconds;(double);generated", - "kotlin.time;Duration$Companion;nanoseconds;(int);generated", - "kotlin.time;Duration$Companion;nanoseconds;(long);generated", - "kotlin.time;Duration$Companion;parse;(String);generated", - "kotlin.time;Duration$Companion;parseIsoString;(String);generated", - "kotlin.time;Duration$Companion;parseIsoStringOrNull;(String);generated", - "kotlin.time;Duration$Companion;parseOrNull;(String);generated", - "kotlin.time;Duration$Companion;seconds;(double);generated", - "kotlin.time;Duration$Companion;seconds;(int);generated", - "kotlin.time;Duration$Companion;seconds;(long);generated", - "kotlin.time;Duration;div;(Duration);generated", - "kotlin.time;Duration;equals;(Object);generated", - "kotlin.time;Duration;getInDays;();generated", - "kotlin.time;Duration;getInHours;();generated", - "kotlin.time;Duration;getInMicroseconds;();generated", - "kotlin.time;Duration;getInMilliseconds;();generated", - "kotlin.time;Duration;getInMinutes;();generated", - "kotlin.time;Duration;getInNanoseconds;();generated", - "kotlin.time;Duration;getInSeconds;();generated", - "kotlin.time;Duration;getInWholeDays;();generated", - "kotlin.time;Duration;getInWholeHours;();generated", - "kotlin.time;Duration;getInWholeMicroseconds;();generated", - "kotlin.time;Duration;getInWholeMilliseconds;();generated", - "kotlin.time;Duration;getInWholeMinutes;();generated", - "kotlin.time;Duration;getInWholeNanoseconds;();generated", - "kotlin.time;Duration;getInWholeSeconds;();generated", - "kotlin.time;Duration;hashCode;();generated", "kotlin.time;Duration;isFinite;();generated", - "kotlin.time;Duration;isInfinite;();generated", - "kotlin.time;Duration;isNegative;();generated", - "kotlin.time;Duration;isPositive;();generated", - "kotlin.time;Duration;toComponents;(Function2);generated", - "kotlin.time;Duration;toComponents;(Function3);generated", - "kotlin.time;Duration;toComponents;(Function4);generated", - "kotlin.time;Duration;toComponents;(Function5);generated", - "kotlin.time;Duration;toDouble;(DurationUnit);generated", - "kotlin.time;Duration;toInt;(DurationUnit);generated", - "kotlin.time;Duration;toIsoString;();generated", - "kotlin.time;Duration;toLong;(DurationUnit);generated", - "kotlin.time;Duration;toLongMilliseconds;();generated", - "kotlin.time;Duration;toLongNanoseconds;();generated", - "kotlin.time;Duration;toString;();generated", - "kotlin.time;Duration;toString;(DurationUnit,int);generated", - "kotlin.time;Duration;unaryMinus;();generated", - "kotlin.time;DurationKt;getDays;(double);generated", - "kotlin.time;DurationKt;getDays;(int);generated", - "kotlin.time;DurationKt;getDays;(long);generated", - "kotlin.time;DurationKt;getHours;(double);generated", - "kotlin.time;DurationKt;getHours;(int);generated", - "kotlin.time;DurationKt;getHours;(long);generated", - "kotlin.time;DurationKt;getMicroseconds;(double);generated", - "kotlin.time;DurationKt;getMicroseconds;(int);generated", - "kotlin.time;DurationKt;getMicroseconds;(long);generated", - "kotlin.time;DurationKt;getMilliseconds;(double);generated", - "kotlin.time;DurationKt;getMilliseconds;(int);generated", - "kotlin.time;DurationKt;getMilliseconds;(long);generated", - "kotlin.time;DurationKt;getMinutes;(double);generated", - "kotlin.time;DurationKt;getMinutes;(int);generated", - "kotlin.time;DurationKt;getMinutes;(long);generated", - "kotlin.time;DurationKt;getNanoseconds;(double);generated", - "kotlin.time;DurationKt;getNanoseconds;(int);generated", - "kotlin.time;DurationKt;getNanoseconds;(long);generated", - "kotlin.time;DurationKt;getSeconds;(double);generated", - "kotlin.time;DurationKt;getSeconds;(int);generated", - "kotlin.time;DurationKt;getSeconds;(long);generated", - "kotlin.time;DurationKt;toDuration;(double,DurationUnit);generated", - "kotlin.time;DurationKt;toDuration;(int,DurationUnit);generated", - "kotlin.time;DurationKt;toDuration;(long,DurationUnit);generated", - "kotlin.time;DurationUnit;valueOf;(String);generated", - "kotlin.time;DurationUnit;values;();generated", - "kotlin.time;DurationUnitKt;toDurationUnit;(TimeUnit);generated", - "kotlin.time;DurationUnitKt;toTimeUnit;(DurationUnit);generated", - "kotlin.time;ExperimentalTime;ExperimentalTime;();generated", - "kotlin.time;MeasureTimeKt;measureTime;(Function0);generated", - "kotlin.time;MeasureTimeKt;measureTime;(Monotonic,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTime;(TimeSource,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(Monotonic,Function0);generated", - "kotlin.time;MeasureTimeKt;measureTimedValue;(TimeSource,Function0);generated", - "kotlin.time;TestTimeSource;TestTimeSource;();generated", - "kotlin.time;TestTimeSource;plusAssign;(Duration);generated", - "kotlin.time;TimeMark;elapsedNow;();generated", - "kotlin.time;TimeMark;hasNotPassedNow;();generated", - "kotlin.time;TimeMark;hasPassedNow;();generated", - "kotlin.time;TimeMark;minus;(Duration);generated", - "kotlin.time;TimeMark;plus;(Duration);generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;equals;(Object);generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;hashCode;();generated", - "kotlin.time;TimeSource$Monotonic$ValueTimeMark;toString;();generated", - "kotlin.time;TimeSource$Monotonic;toString;();generated", - "kotlin.time;TimeSource;markNow;();generated", - "kotlin.time;TimeSourceKt;compareTo;(TimeMark,TimeMark);generated", - "kotlin.time;TimeSourceKt;minus;(TimeMark,TimeMark);generated", - "kotlin.time;TimedValue;equals;(Object);generated", - "kotlin.time;TimedValue;hashCode;();generated", - "kotlin;ArithmeticException;ArithmeticException;();generated", - "kotlin;ArithmeticException;ArithmeticException;(String);generated", - "kotlin;ArrayIntrinsicsKt;emptyArray;();generated", - "kotlin;AssertionError;AssertionError;();generated", - "kotlin;AssertionError;AssertionError;(Object);generated", - "kotlin;BuilderInference;BuilderInference;();generated", - "kotlin;CharCodeJVMKt;Char;(short);generated", "kotlin;CharCodeKt;Char;(int);generated", - "kotlin;CharCodeKt;Char;(short);generated", "kotlin;CharCodeKt;getCode;(char);generated", - "kotlin;ClassCastException;ClassCastException;();generated", - "kotlin;ClassCastException;ClassCastException;(String);generated", - "kotlin;Comparator;compare;(Object,Object);generated", - "kotlin;CompareToKt;compareTo;(Comparable,Object);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;();generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(String);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(String,Throwable);generated", - "kotlin;ConcurrentModificationException;ConcurrentModificationException;(Throwable);generated", - "kotlin;ContextFunctionTypeParams;ContextFunctionTypeParams;(int);generated", - "kotlin;ContextFunctionTypeParams;count;();generated", - "kotlin;DeepRecursiveKt;invoke;(DeepRecursiveFunction,Object);generated", - "kotlin;DeepRecursiveScope;callRecursive;(DeepRecursiveFunction,Object);generated", - "kotlin;DeepRecursiveScope;callRecursive;(Object);generated", - "kotlin;DeepRecursiveScope;invoke;(DeepRecursiveFunction,Object);generated", - "kotlin;Deprecated;Deprecated;(String,ReplaceWith,DeprecationLevel);generated", - "kotlin;Deprecated;level;();generated", "kotlin;Deprecated;message;();generated", - "kotlin;Deprecated;replaceWith;();generated", - "kotlin;DeprecatedSinceKotlin;DeprecatedSinceKotlin;(String,String,String);generated", - "kotlin;DeprecatedSinceKotlin;errorSince;();generated", - "kotlin;DeprecatedSinceKotlin;hiddenSince;();generated", - "kotlin;DeprecatedSinceKotlin;warningSince;();generated", - "kotlin;DeprecationLevel;valueOf;(String);generated", - "kotlin;DeprecationLevel;values;();generated", "kotlin;DslMarker;DslMarker;();generated", - "kotlin;Error;Error;();generated", "kotlin;Error;Error;(String);generated", - "kotlin;Error;Error;(String,Throwable);generated", - "kotlin;Error;Error;(Throwable);generated", "kotlin;Exception;Exception;();generated", - "kotlin;Exception;Exception;(String);generated", - "kotlin;Exception;Exception;(String,Throwable);generated", - "kotlin;Exception;Exception;(Throwable);generated", - "kotlin;ExceptionsHKt;addSuppressed;(Throwable,Throwable);generated", - "kotlin;ExceptionsHKt;getSuppressedExceptions;(Throwable);generated", - "kotlin;ExceptionsHKt;printStackTrace;(Throwable);generated", - "kotlin;ExceptionsHKt;stackTraceToString;(Throwable);generated", - "kotlin;ExceptionsKt;addSuppressed;(Throwable,Throwable);generated", - "kotlin;ExceptionsKt;getStackTrace;(Throwable);generated", - "kotlin;ExceptionsKt;getSuppressedExceptions;(Throwable);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable,PrintStream);generated", - "kotlin;ExceptionsKt;printStackTrace;(Throwable,PrintWriter);generated", - "kotlin;ExceptionsKt;stackTraceToString;(Throwable);generated", - "kotlin;Experimental$Level;valueOf;(String);generated", - "kotlin;Experimental$Level;values;();generated", - "kotlin;Experimental;Experimental;(Level);generated", - "kotlin;Experimental;level;();generated", - "kotlin;ExperimentalMultiplatform;ExperimentalMultiplatform;();generated", - "kotlin;ExperimentalStdlibApi;ExperimentalStdlibApi;();generated", - "kotlin;ExperimentalUnsignedTypes;ExperimentalUnsignedTypes;();generated", - "kotlin;ExtensionFunctionType;ExtensionFunctionType;();generated", - "kotlin;HashCodeKt;hashCode;(Object);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;();generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(String);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(String,Throwable);generated", - "kotlin;IllegalArgumentException;IllegalArgumentException;(Throwable);generated", - "kotlin;IllegalStateException;IllegalStateException;();generated", - "kotlin;IllegalStateException;IllegalStateException;(String);generated", - "kotlin;IllegalStateException;IllegalStateException;(String,Throwable);generated", - "kotlin;IllegalStateException;IllegalStateException;(Throwable);generated", - "kotlin;IndexOutOfBoundsException;IndexOutOfBoundsException;();generated", - "kotlin;IndexOutOfBoundsException;IndexOutOfBoundsException;(String);generated", - "kotlin;KotlinHKt;fromBits;(DoubleCompanionObject,long);generated", - "kotlin;KotlinHKt;fromBits;(FloatCompanionObject,int);generated", - "kotlin;KotlinHKt;isFinite;(double);generated", - "kotlin;KotlinHKt;isFinite;(float);generated", - "kotlin;KotlinHKt;isInfinite;(double);generated", - "kotlin;KotlinHKt;isInfinite;(float);generated", - "kotlin;KotlinHKt;isNaN;(double);generated", "kotlin;KotlinHKt;isNaN;(float);generated", - "kotlin;KotlinHKt;lazy;(Function0);generated", - "kotlin;KotlinHKt;lazy;(LazyThreadSafetyMode,Function0);generated", - "kotlin;KotlinHKt;lazy;(Object,Function0);generated", - "kotlin;KotlinHKt;toBits;(double);generated", "kotlin;KotlinHKt;toBits;(float);generated", - "kotlin;KotlinHKt;toRawBits;(double);generated", - "kotlin;KotlinHKt;toRawBits;(float);generated", - "kotlin;KotlinNullPointerException;KotlinNullPointerException;();generated", - "kotlin;KotlinNullPointerException;KotlinNullPointerException;(String);generated", - "kotlin;KotlinVersion$Companion;getMAX_COMPONENT_VALUE;();generated", - "kotlin;KotlinVersion;KotlinVersion;(int,int);generated", - "kotlin;KotlinVersion;KotlinVersion;(int,int,int);generated", - "kotlin;KotlinVersion;equals;(Object);generated", - "kotlin;KotlinVersion;getMajor;();generated", "kotlin;KotlinVersion;getMinor;();generated", - "kotlin;KotlinVersion;getPatch;();generated", "kotlin;KotlinVersion;hashCode;();generated", - "kotlin;KotlinVersion;isAtLeast;(int,int);generated", - "kotlin;KotlinVersion;isAtLeast;(int,int,int);generated", - "kotlin;KotlinVersion;toString;();generated", - "kotlin;LateinitKt;isInitialized;(KProperty0);generated", - "kotlin;Lazy;getValue;();generated", "kotlin;Lazy;isInitialized;();generated", - "kotlin;LazyThreadSafetyMode;valueOf;(String);generated", - "kotlin;LazyThreadSafetyMode;values;();generated", - "kotlin;Metadata;Metadata;(int,int[],int[],String[],String[],String,String,int);generated", - "kotlin;Metadata;bv;();generated", "kotlin;Metadata;d1;();generated", - "kotlin;Metadata;d2;();generated", "kotlin;Metadata;k;();generated", - "kotlin;Metadata;mv;();generated", "kotlin;Metadata;pn;();generated", - "kotlin;Metadata;xi;();generated", "kotlin;Metadata;xs;();generated", - "kotlin;NoSuchElementException;NoSuchElementException;();generated", - "kotlin;NoSuchElementException;NoSuchElementException;(String);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;();generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(String);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(String,Throwable);generated", - "kotlin;NoWhenBranchMatchedException;NoWhenBranchMatchedException;(Throwable);generated", - "kotlin;NotImplementedError;NotImplementedError;(String);generated", - "kotlin;NullPointerException;NullPointerException;();generated", - "kotlin;NullPointerException;NullPointerException;(String);generated", - "kotlin;NumberFormatException;NumberFormatException;();generated", - "kotlin;NumberFormatException;NumberFormatException;(String);generated", - "kotlin;NumbersKt;and;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(byte);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(int);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(long);generated", - "kotlin;NumbersKt;countLeadingZeroBits;(short);generated", - "kotlin;NumbersKt;countOneBits;(byte);generated", - "kotlin;NumbersKt;countOneBits;(int);generated", - "kotlin;NumbersKt;countOneBits;(long);generated", - "kotlin;NumbersKt;countOneBits;(short);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(byte);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(int);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(long);generated", - "kotlin;NumbersKt;countTrailingZeroBits;(short);generated", - "kotlin;NumbersKt;dec;(BigDecimal);generated", - "kotlin;NumbersKt;dec;(BigInteger);generated", - "kotlin;NumbersKt;div;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;div;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;floorDiv;(byte,byte);generated", - "kotlin;NumbersKt;floorDiv;(byte,int);generated", - "kotlin;NumbersKt;floorDiv;(byte,long);generated", - "kotlin;NumbersKt;floorDiv;(byte,short);generated", - "kotlin;NumbersKt;floorDiv;(int,byte);generated", - "kotlin;NumbersKt;floorDiv;(int,int);generated", - "kotlin;NumbersKt;floorDiv;(int,long);generated", - "kotlin;NumbersKt;floorDiv;(int,short);generated", - "kotlin;NumbersKt;floorDiv;(long,byte);generated", - "kotlin;NumbersKt;floorDiv;(long,int);generated", - "kotlin;NumbersKt;floorDiv;(long,long);generated", - "kotlin;NumbersKt;floorDiv;(long,short);generated", - "kotlin;NumbersKt;floorDiv;(short,byte);generated", - "kotlin;NumbersKt;floorDiv;(short,int);generated", - "kotlin;NumbersKt;floorDiv;(short,long);generated", - "kotlin;NumbersKt;floorDiv;(short,short);generated", - "kotlin;NumbersKt;fromBits;(DoubleCompanionObject,long);generated", - "kotlin;NumbersKt;fromBits;(FloatCompanionObject,int);generated", - "kotlin;NumbersKt;inc;(BigDecimal);generated", - "kotlin;NumbersKt;inc;(BigInteger);generated", - "kotlin;NumbersKt;inv;(BigInteger);generated", - "kotlin;NumbersKt;isFinite;(double);generated", - "kotlin;NumbersKt;isFinite;(float);generated", - "kotlin;NumbersKt;isInfinite;(double);generated", - "kotlin;NumbersKt;isInfinite;(float);generated", - "kotlin;NumbersKt;isNaN;(double);generated", "kotlin;NumbersKt;isNaN;(float);generated", - "kotlin;NumbersKt;minus;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;minus;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;mod;(byte,byte);generated", "kotlin;NumbersKt;mod;(byte,int);generated", - "kotlin;NumbersKt;mod;(byte,long);generated", "kotlin;NumbersKt;mod;(byte,short);generated", - "kotlin;NumbersKt;mod;(double,double);generated", - "kotlin;NumbersKt;mod;(double,float);generated", - "kotlin;NumbersKt;mod;(float,double);generated", - "kotlin;NumbersKt;mod;(float,float);generated", "kotlin;NumbersKt;mod;(int,byte);generated", - "kotlin;NumbersKt;mod;(int,int);generated", "kotlin;NumbersKt;mod;(int,long);generated", - "kotlin;NumbersKt;mod;(int,short);generated", "kotlin;NumbersKt;mod;(long,byte);generated", - "kotlin;NumbersKt;mod;(long,int);generated", "kotlin;NumbersKt;mod;(long,long);generated", - "kotlin;NumbersKt;mod;(long,short);generated", - "kotlin;NumbersKt;mod;(short,byte);generated", "kotlin;NumbersKt;mod;(short,int);generated", - "kotlin;NumbersKt;mod;(short,long);generated", - "kotlin;NumbersKt;mod;(short,short);generated", - "kotlin;NumbersKt;or;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;plus;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;plus;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;rem;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;rem;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;rotateLeft;(byte,int);generated", - "kotlin;NumbersKt;rotateLeft;(int,int);generated", - "kotlin;NumbersKt;rotateLeft;(long,int);generated", - "kotlin;NumbersKt;rotateLeft;(short,int);generated", - "kotlin;NumbersKt;rotateRight;(byte,int);generated", - "kotlin;NumbersKt;rotateRight;(int,int);generated", - "kotlin;NumbersKt;rotateRight;(long,int);generated", - "kotlin;NumbersKt;rotateRight;(short,int);generated", - "kotlin;NumbersKt;shl;(BigInteger,int);generated", - "kotlin;NumbersKt;shr;(BigInteger,int);generated", - "kotlin;NumbersKt;takeHighestOneBit;(byte);generated", - "kotlin;NumbersKt;takeHighestOneBit;(int);generated", - "kotlin;NumbersKt;takeHighestOneBit;(long);generated", - "kotlin;NumbersKt;takeHighestOneBit;(short);generated", - "kotlin;NumbersKt;takeLowestOneBit;(byte);generated", - "kotlin;NumbersKt;takeLowestOneBit;(int);generated", - "kotlin;NumbersKt;takeLowestOneBit;(long);generated", - "kotlin;NumbersKt;takeLowestOneBit;(short);generated", - "kotlin;NumbersKt;times;(BigDecimal,BigDecimal);generated", - "kotlin;NumbersKt;times;(BigInteger,BigInteger);generated", - "kotlin;NumbersKt;toBigDecimal;(BigInteger);generated", - "kotlin;NumbersKt;toBigDecimal;(BigInteger,int,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(double);generated", - "kotlin;NumbersKt;toBigDecimal;(double,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(float);generated", - "kotlin;NumbersKt;toBigDecimal;(float,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(int);generated", - "kotlin;NumbersKt;toBigDecimal;(int,MathContext);generated", - "kotlin;NumbersKt;toBigDecimal;(long);generated", - "kotlin;NumbersKt;toBigDecimal;(long,MathContext);generated", - "kotlin;NumbersKt;toBigInteger;(int);generated", - "kotlin;NumbersKt;toBigInteger;(long);generated", - "kotlin;NumbersKt;toBits;(double);generated", "kotlin;NumbersKt;toBits;(float);generated", - "kotlin;NumbersKt;toRawBits;(double);generated", - "kotlin;NumbersKt;toRawBits;(float);generated", - "kotlin;NumbersKt;unaryMinus;(BigDecimal);generated", - "kotlin;NumbersKt;unaryMinus;(BigInteger);generated", - "kotlin;NumbersKt;xor;(BigInteger,BigInteger);generated", - "kotlin;OptIn;OptIn;(KClass[]);generated", "kotlin;OptIn;markerClass;();generated", - "kotlin;OptionalExpectation;OptionalExpectation;();generated", - "kotlin;OverloadResolutionByLambdaReturnType;OverloadResolutionByLambdaReturnType;();generated", - "kotlin;Pair;equals;(Object);generated", "kotlin;Pair;hashCode;();generated", - "kotlin;ParameterName;ParameterName;(String);generated", - "kotlin;ParameterName;name;();generated", - "kotlin;PreconditionsKt;assert;(boolean);generated", - "kotlin;PreconditionsKt;assert;(boolean,Function0);generated", - "kotlin;PreconditionsKt;check;(boolean);generated", - "kotlin;PreconditionsKt;check;(boolean,Function0);generated", - "kotlin;PreconditionsKt;error;(Object);generated", - "kotlin;PreconditionsKt;require;(boolean);generated", - "kotlin;PreconditionsKt;require;(boolean,Function0);generated", - "kotlin;PropertyReferenceDelegatesKt;getValue;(KProperty0,Object,KProperty);generated", - "kotlin;PropertyReferenceDelegatesKt;getValue;(KProperty1,Object,KProperty);generated", - "kotlin;PropertyReferenceDelegatesKt;setValue;(KMutableProperty0,Object,KProperty,Object);generated", - "kotlin;PropertyReferenceDelegatesKt;setValue;(KMutableProperty1,Object,KProperty,Object);generated", - "kotlin;PublishedApi;PublishedApi;();generated", - "kotlin;ReplaceWith;ReplaceWith;(String,String[]);generated", - "kotlin;ReplaceWith;expression;();generated", "kotlin;ReplaceWith;imports;();generated", - "kotlin;RequiresOptIn$Level;valueOf;(String);generated", - "kotlin;RequiresOptIn$Level;values;();generated", - "kotlin;RequiresOptIn;RequiresOptIn;(String,Level);generated", - "kotlin;RequiresOptIn;level;();generated", "kotlin;RequiresOptIn;message;();generated", - "kotlin;Result;equals;(Object);generated", "kotlin;Result;hashCode;();generated", - "kotlin;Result;isFailure;();generated", "kotlin;Result;isSuccess;();generated", - "kotlin;ResultKt;runCatching;(Function0);generated", - "kotlin;ResultKt;runCatching;(Object,Function1);generated", - "kotlin;RuntimeException;RuntimeException;();generated", - "kotlin;RuntimeException;RuntimeException;(String);generated", - "kotlin;RuntimeException;RuntimeException;(String,Throwable);generated", - "kotlin;RuntimeException;RuntimeException;(Throwable);generated", - "kotlin;SinceKotlin;SinceKotlin;(String);generated", - "kotlin;SinceKotlin;version;();generated", "kotlin;StandardKt;TODO;();generated", - "kotlin;StandardKt;TODO;(String);generated", - "kotlin;StandardKt;repeat;(int,Function1);generated", - "kotlin;StandardKt;run;(Function0);generated", - "kotlin;StandardKt;synchronized;(Object,Function0);generated", - "kotlin;Suppress;Suppress;(String[]);generated", "kotlin;Suppress;names;();generated", - "kotlin;Throws;Throws;(KClass[]);generated", "kotlin;Throws;exceptionClasses;();generated", - "kotlin;Triple;equals;(Object);generated", "kotlin;Triple;hashCode;();generated", - "kotlin;TypeCastException;TypeCastException;();generated", - "kotlin;TypeCastException;TypeCastException;(String);generated", - "kotlin;UByte$Companion;getMAX_VALUE;();generated", - "kotlin;UByte$Companion;getMIN_VALUE;();generated", - "kotlin;UByte$Companion;getSIZE_BITS;();generated", - "kotlin;UByte$Companion;getSIZE_BYTES;();generated", "kotlin;UByte;and;(byte);generated", - "kotlin;UByte;compareTo;(byte);generated", "kotlin;UByte;compareTo;(int);generated", - "kotlin;UByte;compareTo;(long);generated", "kotlin;UByte;compareTo;(short);generated", - "kotlin;UByte;dec;();generated", "kotlin;UByte;div;(byte);generated", - "kotlin;UByte;div;(int);generated", "kotlin;UByte;div;(long);generated", - "kotlin;UByte;div;(short);generated", "kotlin;UByte;equals;(Object);generated", - "kotlin;UByte;floorDiv;(byte);generated", "kotlin;UByte;floorDiv;(int);generated", - "kotlin;UByte;floorDiv;(long);generated", "kotlin;UByte;floorDiv;(short);generated", - "kotlin;UByte;hashCode;();generated", "kotlin;UByte;inc;();generated", - "kotlin;UByte;inv;();generated", "kotlin;UByte;minus;(byte);generated", - "kotlin;UByte;minus;(int);generated", "kotlin;UByte;minus;(long);generated", - "kotlin;UByte;minus;(short);generated", "kotlin;UByte;mod;(byte);generated", - "kotlin;UByte;mod;(int);generated", "kotlin;UByte;mod;(long);generated", - "kotlin;UByte;mod;(short);generated", "kotlin;UByte;or;(byte);generated", - "kotlin;UByte;plus;(byte);generated", "kotlin;UByte;plus;(int);generated", - "kotlin;UByte;plus;(long);generated", "kotlin;UByte;plus;(short);generated", - "kotlin;UByte;rangeTo;(byte);generated", "kotlin;UByte;rem;(byte);generated", - "kotlin;UByte;rem;(int);generated", "kotlin;UByte;rem;(long);generated", - "kotlin;UByte;rem;(short);generated", "kotlin;UByte;times;(byte);generated", - "kotlin;UByte;times;(int);generated", "kotlin;UByte;times;(long);generated", - "kotlin;UByte;times;(short);generated", "kotlin;UByte;toByte;();generated", - "kotlin;UByte;toDouble;();generated", "kotlin;UByte;toFloat;();generated", - "kotlin;UByte;toInt;();generated", "kotlin;UByte;toLong;();generated", - "kotlin;UByte;toShort;();generated", "kotlin;UByte;toString;();generated", - "kotlin;UByte;toUInt;();generated", "kotlin;UByte;toULong;();generated", - "kotlin;UByte;toUShort;();generated", "kotlin;UByte;xor;(byte);generated", - "kotlin;UByteArray;UByteArray;(int);generated", - "kotlin;UByteArray;equals;(Object);generated", "kotlin;UByteArray;get;(int);generated", - "kotlin;UByteArray;hashCode;();generated", "kotlin;UByteArray;set;(int,byte);generated", - "kotlin;UByteArray;toString;();generated", - "kotlin;UByteArrayKt;UByteArray;(int,Function1);generated", - "kotlin;UByteKt;toUByte;(byte);generated", "kotlin;UByteKt;toUByte;(int);generated", - "kotlin;UByteKt;toUByte;(long);generated", "kotlin;UByteKt;toUByte;(short);generated", - "kotlin;UInt$Companion;getMAX_VALUE;();generated", - "kotlin;UInt$Companion;getMIN_VALUE;();generated", - "kotlin;UInt$Companion;getSIZE_BITS;();generated", - "kotlin;UInt$Companion;getSIZE_BYTES;();generated", "kotlin;UInt;and;(int);generated", - "kotlin;UInt;compareTo;(byte);generated", "kotlin;UInt;compareTo;(int);generated", - "kotlin;UInt;compareTo;(long);generated", "kotlin;UInt;compareTo;(short);generated", - "kotlin;UInt;dec;();generated", "kotlin;UInt;div;(byte);generated", - "kotlin;UInt;div;(int);generated", "kotlin;UInt;div;(long);generated", - "kotlin;UInt;div;(short);generated", "kotlin;UInt;equals;(Object);generated", - "kotlin;UInt;floorDiv;(byte);generated", "kotlin;UInt;floorDiv;(int);generated", - "kotlin;UInt;floorDiv;(long);generated", "kotlin;UInt;floorDiv;(short);generated", - "kotlin;UInt;hashCode;();generated", "kotlin;UInt;inc;();generated", - "kotlin;UInt;inv;();generated", "kotlin;UInt;minus;(byte);generated", - "kotlin;UInt;minus;(int);generated", "kotlin;UInt;minus;(long);generated", - "kotlin;UInt;minus;(short);generated", "kotlin;UInt;mod;(byte);generated", - "kotlin;UInt;mod;(int);generated", "kotlin;UInt;mod;(long);generated", - "kotlin;UInt;mod;(short);generated", "kotlin;UInt;or;(int);generated", - "kotlin;UInt;plus;(byte);generated", "kotlin;UInt;plus;(int);generated", - "kotlin;UInt;plus;(long);generated", "kotlin;UInt;plus;(short);generated", - "kotlin;UInt;rangeTo;(int);generated", "kotlin;UInt;rem;(byte);generated", - "kotlin;UInt;rem;(int);generated", "kotlin;UInt;rem;(long);generated", - "kotlin;UInt;rem;(short);generated", "kotlin;UInt;shl;(int);generated", - "kotlin;UInt;shr;(int);generated", "kotlin;UInt;times;(byte);generated", - "kotlin;UInt;times;(int);generated", "kotlin;UInt;times;(long);generated", - "kotlin;UInt;times;(short);generated", "kotlin;UInt;toByte;();generated", - "kotlin;UInt;toDouble;();generated", "kotlin;UInt;toFloat;();generated", - "kotlin;UInt;toInt;();generated", "kotlin;UInt;toLong;();generated", - "kotlin;UInt;toShort;();generated", "kotlin;UInt;toString;();generated", - "kotlin;UInt;toUByte;();generated", "kotlin;UInt;toULong;();generated", - "kotlin;UInt;toUShort;();generated", "kotlin;UInt;xor;(int);generated", - "kotlin;UIntArray;UIntArray;(int);generated", "kotlin;UIntArray;equals;(Object);generated", - "kotlin;UIntArray;get;(int);generated", "kotlin;UIntArray;hashCode;();generated", - "kotlin;UIntArray;set;(int,int);generated", "kotlin;UIntArray;toString;();generated", - "kotlin;UIntArrayKt;UIntArray;(int,Function1);generated", - "kotlin;UIntKt;toUInt;(byte);generated", "kotlin;UIntKt;toUInt;(double);generated", - "kotlin;UIntKt;toUInt;(float);generated", "kotlin;UIntKt;toUInt;(int);generated", - "kotlin;UIntKt;toUInt;(long);generated", "kotlin;UIntKt;toUInt;(short);generated", - "kotlin;ULong$Companion;getMAX_VALUE;();generated", - "kotlin;ULong$Companion;getMIN_VALUE;();generated", - "kotlin;ULong$Companion;getSIZE_BITS;();generated", - "kotlin;ULong$Companion;getSIZE_BYTES;();generated", "kotlin;ULong;and;(long);generated", - "kotlin;ULong;compareTo;(byte);generated", "kotlin;ULong;compareTo;(int);generated", - "kotlin;ULong;compareTo;(long);generated", "kotlin;ULong;compareTo;(short);generated", - "kotlin;ULong;dec;();generated", "kotlin;ULong;div;(byte);generated", - "kotlin;ULong;div;(int);generated", "kotlin;ULong;div;(long);generated", - "kotlin;ULong;div;(short);generated", "kotlin;ULong;equals;(Object);generated", - "kotlin;ULong;floorDiv;(byte);generated", "kotlin;ULong;floorDiv;(int);generated", - "kotlin;ULong;floorDiv;(long);generated", "kotlin;ULong;floorDiv;(short);generated", - "kotlin;ULong;hashCode;();generated", "kotlin;ULong;inc;();generated", - "kotlin;ULong;inv;();generated", "kotlin;ULong;minus;(byte);generated", - "kotlin;ULong;minus;(int);generated", "kotlin;ULong;minus;(long);generated", - "kotlin;ULong;minus;(short);generated", "kotlin;ULong;mod;(byte);generated", - "kotlin;ULong;mod;(int);generated", "kotlin;ULong;mod;(long);generated", - "kotlin;ULong;mod;(short);generated", "kotlin;ULong;or;(long);generated", - "kotlin;ULong;plus;(byte);generated", "kotlin;ULong;plus;(int);generated", - "kotlin;ULong;plus;(long);generated", "kotlin;ULong;plus;(short);generated", - "kotlin;ULong;rangeTo;(long);generated", "kotlin;ULong;rem;(byte);generated", - "kotlin;ULong;rem;(int);generated", "kotlin;ULong;rem;(long);generated", - "kotlin;ULong;rem;(short);generated", "kotlin;ULong;shl;(int);generated", - "kotlin;ULong;shr;(int);generated", "kotlin;ULong;times;(byte);generated", - "kotlin;ULong;times;(int);generated", "kotlin;ULong;times;(long);generated", - "kotlin;ULong;times;(short);generated", "kotlin;ULong;toByte;();generated", - "kotlin;ULong;toDouble;();generated", "kotlin;ULong;toFloat;();generated", - "kotlin;ULong;toInt;();generated", "kotlin;ULong;toLong;();generated", - "kotlin;ULong;toShort;();generated", "kotlin;ULong;toString;();generated", - "kotlin;ULong;toUByte;();generated", "kotlin;ULong;toUInt;();generated", - "kotlin;ULong;toUShort;();generated", "kotlin;ULong;xor;(long);generated", - "kotlin;ULongArray;ULongArray;(int);generated", - "kotlin;ULongArray;equals;(Object);generated", "kotlin;ULongArray;get;(int);generated", - "kotlin;ULongArray;hashCode;();generated", "kotlin;ULongArray;set;(int,long);generated", - "kotlin;ULongArray;toString;();generated", - "kotlin;ULongArrayKt;ULongArray;(int,Function1);generated", - "kotlin;ULongKt;toULong;(byte);generated", "kotlin;ULongKt;toULong;(double);generated", - "kotlin;ULongKt;toULong;(float);generated", "kotlin;ULongKt;toULong;(int);generated", - "kotlin;ULongKt;toULong;(long);generated", "kotlin;ULongKt;toULong;(short);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(byte);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(int);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(long);generated", - "kotlin;UNumbersKt;countLeadingZeroBits;(short);generated", - "kotlin;UNumbersKt;countOneBits;(byte);generated", - "kotlin;UNumbersKt;countOneBits;(int);generated", - "kotlin;UNumbersKt;countOneBits;(long);generated", - "kotlin;UNumbersKt;countOneBits;(short);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(byte);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(int);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(long);generated", - "kotlin;UNumbersKt;countTrailingZeroBits;(short);generated", - "kotlin;UNumbersKt;rotateLeft;(byte,int);generated", - "kotlin;UNumbersKt;rotateLeft;(int,int);generated", - "kotlin;UNumbersKt;rotateLeft;(long,int);generated", - "kotlin;UNumbersKt;rotateLeft;(short,int);generated", - "kotlin;UNumbersKt;rotateRight;(byte,int);generated", - "kotlin;UNumbersKt;rotateRight;(int,int);generated", - "kotlin;UNumbersKt;rotateRight;(long,int);generated", - "kotlin;UNumbersKt;rotateRight;(short,int);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(byte);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(int);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(long);generated", - "kotlin;UNumbersKt;takeHighestOneBit;(short);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(byte);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(int);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(long);generated", - "kotlin;UNumbersKt;takeLowestOneBit;(short);generated", - "kotlin;UShort$Companion;getMAX_VALUE;();generated", - "kotlin;UShort$Companion;getMIN_VALUE;();generated", - "kotlin;UShort$Companion;getSIZE_BITS;();generated", - "kotlin;UShort$Companion;getSIZE_BYTES;();generated", "kotlin;UShort;and;(short);generated", - "kotlin;UShort;compareTo;(byte);generated", "kotlin;UShort;compareTo;(int);generated", - "kotlin;UShort;compareTo;(long);generated", "kotlin;UShort;compareTo;(short);generated", - "kotlin;UShort;dec;();generated", "kotlin;UShort;div;(byte);generated", - "kotlin;UShort;div;(int);generated", "kotlin;UShort;div;(long);generated", - "kotlin;UShort;div;(short);generated", "kotlin;UShort;equals;(Object);generated", - "kotlin;UShort;floorDiv;(byte);generated", "kotlin;UShort;floorDiv;(int);generated", - "kotlin;UShort;floorDiv;(long);generated", "kotlin;UShort;floorDiv;(short);generated", - "kotlin;UShort;hashCode;();generated", "kotlin;UShort;inc;();generated", - "kotlin;UShort;inv;();generated", "kotlin;UShort;minus;(byte);generated", - "kotlin;UShort;minus;(int);generated", "kotlin;UShort;minus;(long);generated", - "kotlin;UShort;minus;(short);generated", "kotlin;UShort;mod;(byte);generated", - "kotlin;UShort;mod;(int);generated", "kotlin;UShort;mod;(long);generated", - "kotlin;UShort;mod;(short);generated", "kotlin;UShort;or;(short);generated", - "kotlin;UShort;plus;(byte);generated", "kotlin;UShort;plus;(int);generated", - "kotlin;UShort;plus;(long);generated", "kotlin;UShort;plus;(short);generated", - "kotlin;UShort;rangeTo;(short);generated", "kotlin;UShort;rem;(byte);generated", - "kotlin;UShort;rem;(int);generated", "kotlin;UShort;rem;(long);generated", - "kotlin;UShort;rem;(short);generated", "kotlin;UShort;times;(byte);generated", - "kotlin;UShort;times;(int);generated", "kotlin;UShort;times;(long);generated", - "kotlin;UShort;times;(short);generated", "kotlin;UShort;toByte;();generated", - "kotlin;UShort;toDouble;();generated", "kotlin;UShort;toFloat;();generated", - "kotlin;UShort;toInt;();generated", "kotlin;UShort;toLong;();generated", - "kotlin;UShort;toShort;();generated", "kotlin;UShort;toString;();generated", - "kotlin;UShort;toUByte;();generated", "kotlin;UShort;toUInt;();generated", - "kotlin;UShort;toULong;();generated", "kotlin;UShort;xor;(short);generated", - "kotlin;UShortArray;UShortArray;(int);generated", - "kotlin;UShortArray;equals;(Object);generated", "kotlin;UShortArray;get;(int);generated", - "kotlin;UShortArray;hashCode;();generated", "kotlin;UShortArray;set;(int,short);generated", - "kotlin;UShortArray;toString;();generated", - "kotlin;UShortArrayKt;UShortArray;(int,Function1);generated", - "kotlin;UShortKt;toUShort;(byte);generated", "kotlin;UShortKt;toUShort;(int);generated", - "kotlin;UShortKt;toUShort;(long);generated", "kotlin;UShortKt;toUShort;(short);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;();generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(String);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(String,Throwable);generated", - "kotlin;UninitializedPropertyAccessException;UninitializedPropertyAccessException;(Throwable);generated", - "kotlin;Unit;toString;();generated", "kotlin;UnsafeVariance;UnsafeVariance;();generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;();generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(String);generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(String,Throwable);generated", - "kotlin;UnsupportedOperationException;UnsupportedOperationException;(Throwable);generated", - "kotlin;UseExperimental;UseExperimental;(KClass[]);generated", - "kotlin;UseExperimental;markerClass;();generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll deleted file mode 100644 index 3d70961cf37..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLib.qll +++ /dev/null @@ -1,14 +0,0 @@ -/** Definitions of taint steps in the KotlinStdLib framework */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class KotlinStdLibSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "kotlin.collections;ArraysKt;false;withIndex;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll deleted file mode 100644 index ed2b0165f47..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/StdLibGenerated.qll +++ /dev/null @@ -1,1868 +0,0 @@ -/** - * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the Kotlin StdLib @30ce58cea74 framework. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StdLibGeneratedSinksCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.io;FilesKt;false;appendBytes;(File,byte[]);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;appendText;(File,String,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;bufferedWriter;(File,Charset,int);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;copyRecursively;(File,File,boolean,Function2);;Argument[1];create-file;generated", - "kotlin.io;FilesKt;false;copyTo;(File,File,boolean,int);;Argument[1];create-file;generated", - "kotlin.io;FilesKt;false;outputStream;(File);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;printWriter;(File,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writeBytes;(File,byte[]);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writeText;(File,String,Charset);;Argument[0];create-file;generated", - "kotlin.io;FilesKt;false;writer;(File,Charset);;Argument[0];create-file;generated", - "kotlin.io;TextStreamsKt;false;readBytes;(URL);;Argument[0];open-url;generated", - "kotlin.io;TextStreamsKt;false;readText;(URL,Charset);;Argument[0];open-url;generated" - ] - } -} - -private class StdLibGeneratedSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "kotlin.collections;AbstractCollection;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;ArrayDeque;(Collection);;Argument[0].Element;Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;addFirst;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;addLast;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.collections;ArrayDeque;false;first;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;firstOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;last;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;lastOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeFirstOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeLast;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArrayDeque;false;removeLastOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;asList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(Object[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(boolean[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(byte[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(char[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(double[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(float[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(int[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(long[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateByTo;(short[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;associateWithTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[0].ArrayElement;Argument[1].ArrayElement;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(Object[],Object[],int,int,int);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(byte[],byte[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyInto;(char[],char[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(byte[],int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOf;(char[],int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(Object[],int,int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;copyOfRangeInline;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;drop;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;dropLast;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;dropLastWhile;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fill;(Object[],Object,int,int);;Argument[1];Argument[0].ArrayElement;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIndexedTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIsInstanceTo;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterIsInstanceTo;(Object[],Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotNullTo;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterNotTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;filterTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;findLast;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;first;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;firstOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedIterableTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapIndexedSequenceTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapSequenceTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;flatMapTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;fold;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRight;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;foldRightIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(Object[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(Object[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(boolean[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(boolean[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(byte[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(byte[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(char[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(char[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(double[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(double[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(float[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(float[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(int[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(int[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(long[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(long[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(short[],Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;groupByTo;(short[],Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;ifEmpty;(Object[],Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(Object[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(boolean[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(byte[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(char[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(double[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(float[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(int[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(long[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;ArraysKt;false;joinTo;(short[],Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(Object[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(boolean[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(byte[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(char[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(double[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(float[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(int[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(long[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;joinToString;(short[],CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;last;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;last;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;lastOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;lastOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedNotNullTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(Object[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(boolean[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(byte[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(char[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(double[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(float[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(int[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(long[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapIndexedTo;(short[],Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapNotNullTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(Object[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(boolean[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(byte[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(char[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(double[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(float[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(int[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(long[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;mapTo;(short[],Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;max;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxByOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxByOrThrow;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOfWith;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOfWithOrNull;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOrNull;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxOrThrow;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWithOrNull;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;maxWithOrThrow;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;min;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minByOrNull;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minByOrThrow;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOfWith;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOfWithOrNull;(Object[],Comparator,Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOrNull;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minOrThrow;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWithOrNull;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;minWithOrThrow;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(byte[],Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEach;(char[],Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(byte[],Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;onEachIndexed;(char[],Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;orEmpty;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Collection);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(Object[],Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(byte[],byte[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plus;(char[],char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;plusElement;(Object[],Object);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduce;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceIndexed;(Object[],Function3);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceIndexedOrNull;(Object[],Function3);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reduceOrNull;(Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;requireNoNulls;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversed;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;reversedArray;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFold;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;runningFoldIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(Object[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(boolean[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(byte[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(char[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(double[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(float[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(int[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(long[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scan;(short[],Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(Object[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(boolean[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(byte[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(char[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(double[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(float[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(int[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(long[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;scanIndexed;(short[],Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;single;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;singleOrNull;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;slice;(Object[],IntRange);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(Object[],Collection);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(Object[],IntRange);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(byte[],IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sliceArray;(char[],IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sorted;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArray;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayDescending;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedArrayWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedBy;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedByDescending;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedDescending;(Comparable[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;sortedWith;(Object[],Comparator);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;take;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;takeLast;(Object[],int);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;takeLastWhile;(Object[],Function1);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(Object[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(boolean[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(byte[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(char[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(double[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(float[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(int[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(long[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toCollection;(short[],Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toMutableList;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toSet;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toString;(byte[],Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;toTypedArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(Object[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(byte[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;union;(char[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable,Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Iterable,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[],Function2);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;ArraysKt;false;zip;(Object[],Object[],Function2);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;addAll;(Collection,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;arrayListOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asIterable;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asReversed;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;asReversedMutable;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associate;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateBy;(Iterable,Function1,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateByTo;(Iterable,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWith;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;associateWithTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component1;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component2;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component3;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component4;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;component5;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;distinct;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;distinctBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;drop;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropLast;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropLastWhile;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;dropWhile;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAt;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAt;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrElse;(Iterable,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrElse;(List,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrNull;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;elementAtOrNull;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;fill;(List,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filter;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIndexedTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstance;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstance;(Iterable,Class);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterIsInstanceTo;(Iterable,Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNot;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotNullTo;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterNotTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;filterTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;find;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;findLast;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;findLast;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;first;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstNotNullOf;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstNotNullOfOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;firstOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapIndexedIterableTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapIndexedSequenceTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapSequenceTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatMapTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;flatten;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;fold;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldRight;(List,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;foldRightIndexed;(List,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;getOrElse;(List,int,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;getOrNull;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;groupByTo;(Iterable,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;groupByTo;(Iterable,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;ifEmpty;(Collection,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;intersect;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;iterator;(Iterator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.collections;CollectionsKt;false;joinTo;(Iterable,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;joinToString;(Iterable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;last;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;lastOrNull;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;listOfNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;map;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapIndexedNotNullTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapIndexedTo;(Iterable,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapNotNullTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mapTo;(Iterable,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;max;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxByOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxByOrThrow;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOfWith;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOfWithOrNull;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxOrThrow;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWithOrNull;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;maxWithOrThrow;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;min;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minByOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minByOrThrow;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOfWith;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOfWithOrNull;(Iterable,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minOrThrow;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWithOrNull;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minWithOrThrow;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minus;(Iterable,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;minusElement;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;mutableListOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;onEach;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;onEachIndexed;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;orEmpty;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;orEmpty;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;partition;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Collection,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plus;(Iterable,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Object[]);;Argument[1].ArrayElement;Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusAssign;(Collection,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Collection,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Collection,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Iterable,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;plusElement;(Iterable,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;random;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;random;(Collection,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;randomOrNull;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;randomOrNull;(Collection,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduce;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceIndexed;(Iterable,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceIndexedOrNull;(Iterable,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceOrNull;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRight;(List,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightIndexed;(List,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightIndexedOrNull;(List,Function3);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reduceRightOrNull;(List,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;remove;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeFirst;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeFirstOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeLast;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;removeLastOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;requireNoNulls;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;requireNoNulls;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;reversed;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;runningFold;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;runningFoldIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;scan;(Iterable,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;scanIndexed;(Iterable,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;shuffled;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;shuffled;(Iterable,Random);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;single;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;singleOrNull;(List);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;slice;(List,IntRange);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;slice;(List,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sorted;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedBy;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedByDescending;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedDescending;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;sortedWith;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;subtract;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;take;(Iterable,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeLast;(List,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeLastWhile;(List,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;takeWhile;(Iterable,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toCollection;(Iterable,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toHashSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toList;(Enumeration);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toList;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableList;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableList;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toMutableSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSortedSet;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;toSortedSet;(Iterable,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;union;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;union;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;unzip;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;withIndex;(Iterator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Iterable,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[],Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zip;(Iterable,Object[],Function2);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zipWithNext;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;CollectionsKt;false;zipWithNext;(Iterable,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;aggregateTo;(Grouping,Map,Function4);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;eachCountTo;(Grouping,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;foldTo;(Grouping,Map,Function2,Function3);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;foldTo;(Grouping,Map,Object,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;GroupingKt;false;reduceTo;(Grouping,Map,Function3);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;IndexedValue;(int,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin.collections;IndexedValue;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;copy;(int,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;IndexedValue;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;getValue;(Map,Object,KProperty);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;getVar;(Map,Object,KProperty);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapAccessorsKt;false;setValue;(Map,Object,KProperty,Object);;Argument[2];Argument[0].Element;taint;generated", - "kotlin.collections;MapAccessorsKt;false;setValue;(Map,Object,KProperty,Object);;Argument[3];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;asIterable;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;component1;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;component2;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filter;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterKeys;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNot;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterNotTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;filterValues;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;firstNotNullOf;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;firstNotNullOfOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;flatMapSequenceTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;flatMapTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;get;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrElse;(Map,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(ConcurrentMap,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(Map,Object,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;getOrPut;(Map,Object,Function0);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;getValue;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;ifEmpty;(Map,Function0);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;iterator;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;map;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeys;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapKeysTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapNotNullTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapOf;(Pair);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapTo;(Map,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValues;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mapValuesTo;(Map,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxBy;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxByOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxByOrThrow;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxOfWith;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxOfWithOrNull;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWith;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWithOrNull;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;maxWithOrThrow;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minBy;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minByOrNull;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minByOrThrow;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minOfWith;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minOfWithOrNull;(Map,Comparator,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWith;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWithOrNull;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minWithOrThrow;(Map,Comparator);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;minus;(Map,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;mutableIterator;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;onEach;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;onEachIndexed;(Map,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;orEmpty;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Pair[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plus;(Map,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Map);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Pair);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;plusAssign;(Map,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;putAll;(Map,Iterable);;Argument[1].Element;Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;putAll;(Map,Sequence);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;remove;(Map,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;set;(Map,Object,Object);;Argument[1];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;set;(Map,Object,Object);;Argument[2];Argument[0].Element;taint;generated", - "kotlin.collections;MapsKt;false;toList;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Iterable,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Map,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Pair[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Pair[],Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMap;(Sequence,Map);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toMutableMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toPair;(Entry);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;toSortedMap;(Map);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefault;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefault;(Map,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefaultMutable;(Map,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;MapsKt;false;withDefaultMutable;(Map,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minus;(Set,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;minusElement;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;orEmpty;(Set);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Iterable);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Iterable);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Sequence);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plus;(Set,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plusElement;(Set,Object);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;plusElement;(Set,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOf;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.collections;SetsKt;false;setOfNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;asByteArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;asUByteArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UByteArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UIntArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(ULongArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;associateWithTo;(UShortArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;contentToString;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[0].Element;Argument[1].Element;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UByteArray,UByteArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UIntArray,UIntArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(ULongArray,ULongArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyInto;(UShortArray,UShortArray,int,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOf;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOf;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;copyOfRange;(UByteArray,int,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;drop;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLast;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;dropLastWhile;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterNotTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;filterTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;flatMapTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;fold;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRight;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;foldRightIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UByteArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UByteArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UIntArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UIntArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(ULongArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(ULongArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UShortArray,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;groupByTo;(UShortArray,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UByteArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UIntArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(ULongArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapIndexedTo;(UShortArray,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UByteArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UIntArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(ULongArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;mapTo;(UShortArray,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEach;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UByteArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UIntArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(ULongArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;onEachIndexed;(UShortArray,Function2);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,UByteArray);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;plus;(UByteArray,byte);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversed;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;reversedArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFold;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;runningFoldIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UByteArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UIntArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(ULongArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scan;(UShortArray,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UByteArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UIntArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(ULongArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;scanIndexed;(UShortArray,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sliceArray;(UByteArray,IntRange);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArray;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedArrayDescending;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;sortedDescending;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;take;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UByteArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UIntArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(ULongArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLast;(UShortArray,int);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UByteArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UIntArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(ULongArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;takeLastWhile;(UShortArray,Function1);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;toByteArray;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.collections;UArraysKt;false;toUByteArray;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Comparable,Comparable[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object,Object,Comparator);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;maxOf;(Object,Object[],Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Comparable,Comparable[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[1];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object,Object,Comparator);;Argument[2];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;minOf;(Object,Object[],Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.comparisons;ComparisonsKt;false;reversed;(Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines.intrinsics;IntrinsicsKt;false;intercepted;(Continuation);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines.jvm.internal;CoroutineStackFrame;true;getCallerFrame;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;AbstractCoroutineContextElement;true;AbstractCoroutineContextElement;(Key);;Argument[0];Argument[-1];taint;generated", - "kotlin.coroutines;AbstractCoroutineContextKey;true;AbstractCoroutineContextKey;(Key,Function1);;Argument[0];Argument[-1];taint;generated", - "kotlin.coroutines;AbstractCoroutineContextKey;true;AbstractCoroutineContextKey;(Key,Function1);;Argument[1];Argument[-1];taint;generated", - "kotlin.coroutines;CoroutineContext$Element;true;getKey;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;fold;(Object,Function2);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;fold;(Object,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;get;(Key);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;minusKey;(Key);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;minusKey;(Key);;Argument[-1];ReturnValue;value;generated", - "kotlin.coroutines;CoroutineContext;true;plus;(CoroutineContext);;Argument[-1];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContext;true;plus;(CoroutineContext);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContextImplKt;false;getPolymorphicElement;(Element,Key);;Argument[0];ReturnValue;taint;generated", - "kotlin.coroutines;CoroutineContextImplKt;false;minusPolymorphicKey;(Element,Key);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;AccessDeniedException;false;AccessDeniedException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;ByteStreamsKt;false;buffered;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;buffered;(OutputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;bufferedReader;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;byteInputStream;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;copyTo;(InputStream,OutputStream,int);;Argument[0];Argument[1];taint;generated", - "kotlin.io;ByteStreamsKt;false;inputStream;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;inputStream;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;readBytes;(InputStream);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;readBytes;(InputStream,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;ByteStreamsKt;false;reader;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;CloseableKt;false;use;(Closeable,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;FileAlreadyExistsException;false;FileAlreadyExistsException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;FileSystemException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;FileSystemException;true;getFile;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileSystemException;true;getOther;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileSystemException;true;getReason;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;maxDepth;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onEnter;(Function1);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onEnter;(Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onFail;(Function2);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onFail;(Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onLeave;(Function1);;Argument[-1];ReturnValue;taint;generated", - "kotlin.io;FileTreeWalk;false;onLeave;(Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;copyTo;(File,File,boolean,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;relativeToOrSelf;(File,File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolve;(File,File);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolve;(File,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolveSibling;(File,File);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;resolveSibling;(File,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walk;(File,FileWalkDirection);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walkBottomUp;(File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;FilesKt;false;walkTopDown;(File);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[0];Argument[-1];taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.io;NoSuchFileException;false;NoSuchFileException;(File,File,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.io;TextStreamsKt;false;buffered;(Reader,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;buffered;(Writer,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;copyTo;(Reader,Writer,int);;Argument[0];Argument[1];taint;generated", - "kotlin.io;TextStreamsKt;false;forEachLine;(Reader,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;lineSequence;(BufferedReader);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;readText;(Reader);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;reader;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.io;TextStreamsKt;false;useLines;(Reader,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;AdaptedFunctionReference;true;AdaptedFunctionReference;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;generated", - "kotlin.jvm.internal;ArrayIteratorsKt;false;iterator;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ArrayIteratorsKt;false;iterator;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ByteSpreadBuilder;false;toArray;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;compute;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;getBoundReceiver;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CallableReference;true;getSignature;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CharSpreadBuilder;false;toArray;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ClassReference$Companion;false;getClassQualifiedName;(Class);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ClassReference$Companion;false;getClassSimpleName;(Class);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;CollectionToArray;false;toArray;(Collection);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;CollectionToArray;false;toArray;(Collection,Object[]);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;FunctionReference;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReference;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,KDeclarationContainer,String,String);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;FunctionReferenceImpl;true;FunctionReferenceImpl;(int,Object,Class,String,String,int);;Argument[4];Argument[-1];taint;generated", - "kotlin.jvm.internal;Intrinsics;true;stringPlus;(String,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Intrinsics;true;stringPlus;(String,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0;true;MutablePropertyReference0;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference0Impl;true;MutablePropertyReference0Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1;true;MutablePropertyReference1;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference1Impl;true;MutablePropertyReference1Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2;true;MutablePropertyReference2;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2;true;MutablePropertyReference2;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference2Impl;true;MutablePropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;MutablePropertyReference;true;MutablePropertyReference;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PackageReference;false;PackageReference;(Class,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PrimitiveSpreadBuilder;true;addSpread;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0;true;PropertyReference0;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference0Impl;true;PropertyReference0Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1;true;PropertyReference1;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference1Impl;true;PropertyReference1Impl;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2;true;PropertyReference2;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2;true;PropertyReference2;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(Class,String,String,int);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference2Impl;true;PropertyReference2Impl;(KDeclarationContainer,String,String);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;PropertyReference;(Object,Class,String,String,int);;Argument[3];Argument[-1];taint;generated", - "kotlin.jvm.internal;PropertyReference;true;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;function;(FunctionReference);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;getOrCreateKotlinPackage;(Class,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableCollectionType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty0;(MutablePropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty1;(MutablePropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;mutableProperty2;(MutablePropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nothingType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(Class,KTypeProjection,KTypeProjection);;Argument[2];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;nullableTypeOf;(KClassifier);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;platformType;(KType,KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;platformType;(KType,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property0;(PropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property1;(PropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;property2;(PropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;setUpperBounds;(KTypeParameter,KType);;Argument[1];Argument[0];taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection,KTypeProjection);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(Class,KTypeProjection,KTypeProjection);;Argument[2];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeOf;(KClassifier);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeParameter;(Object,String,KVariance,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;Reflection;true;typeParameter;(Object,String,KVariance,boolean);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;function;(FunctionReference);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;getOrCreateKotlinPackage;(Class,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableCollectionType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty0;(MutablePropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty1;(MutablePropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;mutableProperty2;(MutablePropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;nothingType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;platformType;(KType,KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;platformType;(KType,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property0;(PropertyReference0);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property1;(PropertyReference1);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;property2;(PropertyReference2);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;setUpperBounds;(KTypeParameter,List);;Argument[1].Element;Argument[0];taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeOf;(KClassifier,List,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeOf;(KClassifier,List,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeParameter;(Object,String,KVariance,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;ReflectionFactory;true;typeParameter;(Object,String,KVariance,boolean);;Argument[1];ReturnValue;taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;add;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;addSpread;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;toArray;(Object[]);;Argument[-1];Argument[0].ArrayElement;taint;generated", - "kotlin.jvm.internal;SpreadBuilder;true;toArray;(Object[]);;Argument[-1];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableCollection;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableCollection;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterable;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterable;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableIterator;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableList;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableList;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableListIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableListIterator;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMap;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMap;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMapEntry;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableMapEntry;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableSet;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;asMutableSet;(Object,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;beforeCheckcastToFunctionOfArity;(Object,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;beforeCheckcastToFunctionOfArity;(Object,int,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToCollection;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToIterable;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToList;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToListIterator;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToMap;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToMapEntry;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeIntrinsics;true;castToSet;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;TypeParameterReference;(Object,String,KVariance,boolean);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;TypeParameterReference;(Object,String,KVariance,boolean);;Argument[1];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeParameterReference;false;setUpperBounds;(List);;Argument[0].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,KType,int);;Argument[2];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,boolean);;Argument[0];Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;TypeReference;(KClassifier,List,boolean);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.jvm.internal;TypeReference;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.properties;ObservableProperty;true;ObservableProperty;(Object);;Argument[0];Argument[-1];taint;generated", - "kotlin.random;PlatformRandomKt;false;asJavaRandom;(Random);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;PlatformRandomKt;false;asKotlinRandom;(Random);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;Random;true;nextBytes;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;Random;true;nextBytes;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.random;URandomKt;false;nextUBytes;(Random,UByteArray);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.random;URandomKt;false;nextUBytes;(Random,UByteArray,int,int);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.ranges;CharRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;IntRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;LongRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtLeast;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtLeast;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtMost;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceAtMost;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,ClosedFloatingPointRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,ClosedRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;coerceIn;(Comparable,Comparable,Comparable);;Argument[2];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeTo;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeTo;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeUntil;(Comparable,Comparable);;Argument[0];ReturnValue;taint;generated", - "kotlin.ranges;RangesKt;false;rangeUntil;(Comparable,Comparable);;Argument[1];ReturnValue;taint;generated", - "kotlin.ranges;UIntRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.ranges;ULongRange$Companion;false;getEMPTY;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KClasses;false;cast;(KClass,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KClasses;false;safeCast;(KClass,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KType;true;getArguments;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KType;true;getClassifier;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeParameter;true;getName;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeParameter;true;getUpperBounds;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;contravariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;covariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection$Companion;false;invariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;KTypeProjection;(KVariance,KType);;Argument[1];Argument[-1];taint;generated", - "kotlin.reflect;KTypeProjection;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;contravariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;copy;(KVariance,KType);;Argument[1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;covariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;getType;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;invariant;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;KTypeProjection;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.reflect;TypesJVMKt;false;getJavaType;(KType);;Argument[0];ReturnValue;taint;generated", - "kotlin.reflect;WildcardTypeImpl$Companion;false;getSTAR;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.sequences;SequenceScope;true;yieldAll;(Sequence);;Argument[0];Argument[-1];taint;generated", - "kotlin.sequences;SequencesKt;false;asSequence;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateByTo;(Sequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWith;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;associateWithTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;chunked;(Sequence,int,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;constrainOnce;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinct;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinctBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;distinctBy;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;drop;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;dropWhile;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;dropWhile;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAt;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAtOrElse;(Sequence,int,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;elementAtOrNull;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filter;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filter;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIndexedTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstance;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstance;(Sequence,Class);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterIsInstanceTo;(Sequence,Collection,Class);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNot;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNot;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotNullTo;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterNotTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;filterTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;find;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;findLast;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;first;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;first;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstNotNullOf;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstNotNullOfOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;firstOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMap;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMap;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIndexedIterableTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIndexedSequenceTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterable;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterable;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapIterableTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatMapTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flatten;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;flattenSequenceOfIterable;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;fold;(Sequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;foldIndexed;(Sequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Function0,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;generateSequence;(Object,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;groupByTo;(Sequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;groupByTo;(Sequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];Argument[1];taint;generated", - "kotlin.sequences;SequencesKt;false;joinTo;(Sequence,Appendable,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[6];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[2];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[3];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;joinToString;(Sequence,CharSequence,CharSequence,CharSequence,int,CharSequence,Function1);;Argument[5];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;last;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;last;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;lastOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;lastOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;map;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;map;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexed;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexed;(Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNull;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNull;(Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedNotNullTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapIndexedTo;(Sequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNull;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapNotNullTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;mapTo;(Sequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;max;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxByOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxByOrThrow;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOfWith;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOfWithOrNull;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxOrThrow;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWith;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWithOrNull;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;maxWithOrThrow;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;min;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minBy;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minByOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minByOrThrow;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOfWith;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOfWithOrNull;(Sequence,Comparator,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minOrThrow;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWith;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWithOrNull;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minWithOrThrow;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;minus;(Sequence,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;onEach;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;onEachIndexed;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;orEmpty;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;partition;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduce;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceIndexed;(Sequence,Function3);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceIndexedOrNull;(Sequence,Function3);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;reduceOrNull;(Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;requireNoNulls;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;single;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;single;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;singleOrNull;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;singleOrNull;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;take;(Sequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;takeWhile;(Sequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;takeWhile;(Sequence,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[0];Argument[1].Element;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toCollection;(Sequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toHashSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toList;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toMutableList;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toMutableSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSortedSet;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;toSortedSet;(Sequence,Comparator);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;unzip;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;windowed;(Sequence,int,int,boolean,Function1);;Argument[4];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;withIndex;(Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.sequences;SequencesKt;false;zip;(Sequence,Sequence,Function2);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;CharsKt;false;plus;(char,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;MatchGroup;(String,IntRange);;Argument[0];Argument[-1];taint;generated", - "kotlin.text;MatchGroup;false;MatchGroup;(String,IntRange);;Argument[1].Element;Argument[-1];taint;generated", - "kotlin.text;MatchGroup;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;copy;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;copy;(String,IntRange);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;getRange;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchGroup;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component10;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component3;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component4;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component5;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component6;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component7;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component8;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;component9;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;getMatch;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult$Destructured;false;toList;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getDestructured;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getGroupValues;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;getGroups;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;MatchResult;true;next;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;Regex$Companion;false;escape;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;find;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;getOptions;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;matchEntire;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replace;(CharSequence,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replaceFirst;(CharSequence,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;Regex;false;replaceFirst;(CharSequence,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;Regex;false;toPattern;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(byte[],int,int,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;String;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(Appendable,CharSequence[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;append;(StringBuilder,String[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(Appendable,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuffer);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,StringBuilder);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,double);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,float);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,long);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendLine;(StringBuilder,short);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(Appendable,CharSequence,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,CharSequence,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendRange;(StringBuilder,char[],int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(Appendable,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,CharSequence);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,String);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuffer);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,StringBuilder);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,byte);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[1];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,char[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,double);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,float);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,long);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;appendln;(StringBuilder,short);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateByTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateByTo;(CharSequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;associateWithTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;capitalize;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;capitalize;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;clear;(StringBuilder);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;concatToString;(char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;concatToString;(char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decapitalize;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decapitalize;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decodeToString;(byte[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;decodeToString;(byte[],int,int,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;drop;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;drop;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLast;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLast;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLastWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropLastWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;dropWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;encodeToByteArray;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;encodeToByteArray;(String,int,int,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterIndexedTo;(CharSequence,Appendable,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterNotTo;(CharSequence,Appendable,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;filterTo;(CharSequence,Appendable,Function1);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;findAnyOf;(CharSequence,Collection,int,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;findLastAnyOf;(CharSequence,Collection,int,boolean);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;flatMapIndexedIterableTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;flatMapTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;fold;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldRight;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;foldRightIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Locale,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Locale,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,Locale,String,Object[]);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,Locale,String,Object[]);;Argument[3].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,String,Object[]);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;format;(StringCompanionObject,String,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(String,Locale,Object[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(String,Locale,Object[]);;Argument[2].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(StringCompanionObject,Locale,String,Object[]);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;formatNullable;(StringCompanionObject,Locale,String,Object[]);;Argument[3].ArrayElement;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;groupByTo;(CharSequence,Map,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;groupByTo;(CharSequence,Map,Function1,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;ifBlank;(CharSequence,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;ifEmpty;(CharSequence,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[2];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,CharSequence,int,int);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[2];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;insertRange;(StringBuilder,int,char[],int,int);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;intern;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lineSequence;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lines;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lowercase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;lowercase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapIndexedNotNullTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapIndexedTo;(CharSequence,Collection,Function2);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapNotNullTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;mapTo;(CharSequence,Collection,Function1);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;onEach;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;onEachIndexed;(CharSequence,Function2);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;orEmpty;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;padEnd;(CharSequence,int,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;padStart;(CharSequence,int,char);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;prependIndent;(String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removePrefix;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removePrefix;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeRange;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeRange;(CharSequence,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSuffix;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSuffix;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(CharSequence,CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(String,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;removeSurrounding;(String,CharSequence,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;repeat;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(CharSequence,Regex,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replace;(String,char,char,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfter;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfter;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfterLast;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceAfterLast;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBefore;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBefore;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBeforeLast;(String,String,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceBeforeLast;(String,char,String,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(CharSequence,Regex,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(CharSequence,Regex,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(String,String,String,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirst;(String,char,char,boolean);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirstCharWithChar;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceFirstCharWithCharSequence;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,IntRange,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,IntRange,CharSequence);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,int,int,CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;replaceRange;(CharSequence,int,int,CharSequence);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;reversed;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;runningFold;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;runningFoldIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;scan;(CharSequence,Object,Function2);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;scanIndexed;(CharSequence,Object,Function3);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[3];Argument[0];taint;generated", - "kotlin.text;StringsKt;false;setRange;(StringBuilder,int,int,String);;Argument[3];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;slice;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;slice;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;split;(CharSequence,Pattern,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;splitToSequence;(CharSequence,String[],boolean,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;splitToSequence;(CharSequence,char[],boolean,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;subSequence;(CharSequence,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;subSequence;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,IntRange);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substring;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfter;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringAfterLast;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBefore;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,String,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,String,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,char,String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;substringBeforeLast;(String,char,String);;Argument[2];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;take;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;take;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLast;(CharSequence,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLast;(String,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLastWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeLastWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeWhile;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;takeWhile;(String,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toByteArray;(String,Charset);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,char[],int,int,int);;Argument[1];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(String,int,int);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toCharArray;(StringBuilder,char[],int,int,int);;Argument[0];Argument[1];taint;generated", - "kotlin.text;StringsKt;false;toCollection;(CharSequence,Collection);;Argument[1].Element;ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toLowerCase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toLowerCase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toRegex;(Pattern);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toUpperCase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;toUpperCase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trim;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimEnd;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;trimStart;(CharSequence,char[]);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;uppercase;(String);;Argument[0];ReturnValue;taint;generated", - "kotlin.text;StringsKt;false;uppercase;(String,Locale);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;Duration$Companion;false;getINFINITE;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration$Companion;false;getZERO;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;div;(double);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;div;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;getAbsoluteValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;minus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;plus;(Duration);;Argument[-1];ReturnValue;value;generated", - "kotlin.time;Duration;false;times;(double);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;Duration;false;times;(int);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;DurationKt;false;times;(double,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;DurationKt;false;times;(int,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;minus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;plus;(Duration);;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimeMark;true;plus;(Duration);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;TimeSource;true;markNow;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;TimedValue;(Object,Duration);;Argument[0];Argument[-1];taint;generated", - "kotlin.time;TimedValue;false;TimedValue;(Object,Duration);;Argument[1];Argument[-1];taint;generated", - "kotlin.time;TimedValue;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;copy;(Object,Duration);;Argument[0];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;copy;(Object,Duration);;Argument[1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;getDuration;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;getValue;();;Argument[-1];ReturnValue;taint;generated", - "kotlin.time;TimedValue;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;DeepRecursiveFunction;false;DeepRecursiveFunction;(SuspendFunction2);;Argument[0];Argument[-1];taint;generated", - "kotlin;KotlinVersion$Companion;false;getCURRENT;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;getValue;(Lazy,Object,KProperty);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(LazyThreadSafetyMode,Function0);;Argument[1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazy;(Object,Function0);;Argument[1];ReturnValue;taint;generated", - "kotlin;LazyKt;false;lazyOf;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Pair;false;Pair;(Object,Object);;Argument[0];Argument[-1];taint;generated", - "kotlin;Pair;false;Pair;(Object,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin;Pair;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;copy;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Pair;false;copy;(Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;Pair;false;getFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;getSecond;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Pair;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;checkNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;checkNotNull;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;requireNotNull;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;PreconditionsKt;false;requireNotNull;(Object,Function0);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result$Companion;false;failure;(Throwable);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result$Companion;false;success;(Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Result;false;exceptionOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Result;false;getOrNull;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Result;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;ResultKt;false;fold;(Result,Function1,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrDefault;(Result,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrDefault;(Result,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrElse;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;getOrThrow;(Result);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;map;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;mapCatching;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;onFailure;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;onSuccess;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;recover;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;ResultKt;false;recoverCatching;(Result,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;also;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;apply;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;let;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;run;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;takeIf;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;takeUnless;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;StandardKt;false;with;(Object,Function1);;Argument[0];ReturnValue;taint;generated", - "kotlin;SuspendKt;false;suspend;(SuspendFunction0);;Argument[0];ReturnValue;taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[0];Argument[-1];taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[1];Argument[-1];taint;generated", - "kotlin;Triple;false;Triple;(Object,Object,Object);;Argument[2];Argument[-1];taint;generated", - "kotlin;Triple;false;component1;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;component2;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;component3;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;Triple;false;copy;(Object,Object,Object);;Argument[2];ReturnValue;taint;generated", - "kotlin;Triple;false;getFirst;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;getSecond;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;getThird;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;Triple;false;toString;();;Argument[-1];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;to;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;to;(Object,Object);;Argument[1];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;toList;(Pair);;Argument[0];ReturnValue;taint;generated", - "kotlin;TuplesKt;false;toList;(Triple);;Argument[0];ReturnValue;taint;generated", - "kotlin;UByte;false;toUByte;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UByteArrayKt;false;ubyteArrayOf;(UByteArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;UInt;false;toUInt;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UIntArrayKt;false;uintArrayOf;(UIntArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;ULong;false;toULong;();;Argument[-1];ReturnValue;value;generated", - "kotlin;ULongArrayKt;false;ulongArrayOf;(ULongArray);;Argument[0].Element;ReturnValue;taint;generated", - "kotlin;UShort;false;toUShort;();;Argument[-1];ReturnValue;value;generated", - "kotlin;UShortArrayKt;false;ushortArrayOf;(UShortArray);;Argument[0].Element;ReturnValue;taint;generated" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll new file mode 100644 index 00000000000..62eafa9565e --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll @@ -0,0 +1,21 @@ +/** Provides classes and predicates related to `kotlin.text`. */ + +import java + +/** The type `kotlin.text.StringsKt`, where `String` extension methods are declared. */ +class StringsKt extends RefType { + StringsKt() { this.hasQualifiedName("kotlin.text", "StringsKt") } +} + +/** A call to the extension method `String.toRegex` from `kotlin.text`. */ +class KtToRegex extends MethodAccess { + KtToRegex() { + this.getMethod().getDeclaringType() instanceof StringsKt and + this.getMethod().hasName("toRegex") + } + + /** Gets the constant string value being converted to a regex by this call. */ + string getExpressionString() { + result = this.getArgument(0).(CompileTimeConstantExpr).getStringValue() + } +} diff --git a/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll b/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll deleted file mode 100644 index 772ea3866e5..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/ratpack/Ratpack.qll +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Provides classes and predicates related to `ratpack.*`. - */ - -import java -private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Ratpack methods that access user-supplied request data. - */ -private class RatpackHttpSource extends SourceModelCsv { - override predicate row(string row) { - row = - ["ratpack.http;", "ratpack.core.http;"] + - [ - "Request;true;getContentLength;;;ReturnValue;remote;manual", - "Request;true;getCookies;;;ReturnValue;remote;manual", - "Request;true;oneCookie;;;ReturnValue;remote;manual", - "Request;true;getHeaders;;;ReturnValue;remote;manual", - "Request;true;getPath;;;ReturnValue;remote;manual", - "Request;true;getQuery;;;ReturnValue;remote;manual", - "Request;true;getQueryParams;;;ReturnValue;remote;manual", - "Request;true;getRawUri;;;ReturnValue;remote;manual", - "Request;true;getUri;;;ReturnValue;remote;manual", - "Request;true;getBody;;;ReturnValue;remote;manual" - ] - or - // All Context#parse methods that return a Promise are remote flow sources. - row = - ["ratpack.handling;", "ratpack.core.handling;"] + "Context;true;parse;" + - [ - "(java.lang.Class);", "(com.google.common.reflect.TypeToken);", - "(java.lang.Class,java.lang.Object);", - "(com.google.common.reflect.TypeToken,java.lang.Object);", "(ratpack.core.parse.Parse);", - "(ratpack.parse.Parse);" - ] + ";ReturnValue;remote;manual" - } -} - -/** - * Ratpack methods that propagate user-supplied request data as tainted. - */ -private class RatpackModel extends SummaryModelCsv { - override predicate row(string row) { - row = - ["ratpack.http;", "ratpack.core.http;"] + - [ - "TypedData;true;getBuffer;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getBytes;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getContentType;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;getText;;;Argument[-1];ReturnValue;taint;manual", - "TypedData;true;writeTo;;;Argument[-1];Argument[0];taint;manual", - "Headers;true;get;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;getAll;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;getNames;;;Argument[-1];ReturnValue;taint;manual", - "Headers;true;asMultiValueMap;;;Argument[-1];ReturnValue;taint;manual" - ] - or - row = - ["ratpack.form;", "ratpack.core.form;"] + - [ - "UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint;manual", - "Form;true;file;;;Argument[-1];ReturnValue;taint;manual", - "Form;true;files;;;Argument[-1];ReturnValue;taint;manual" - ] - or - row = - ["ratpack.handling;", "ratpack.core.handling;"] + - [ - "Context;true;parse;(ratpack.http.TypedData,ratpack.parse.Parse);;Argument[0];ReturnValue;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue.MapKey;taint;manual", - "Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue.MapValue;taint;manual" - ] - or - row = - ["ratpack.util;", "ratpack.func;"] + - [ - "MultiValueMap;true;getAll;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "MultiValueMap;true;getAll;();;Argument[-1].MapValue;ReturnValue.MapValue.Element;value;manual", - "MultiValueMap;true;getAll;(Object);;Argument[-1].MapValue;ReturnValue.Element;value;manual", - "MultiValueMap;true;asMultimap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "MultiValueMap;true;asMultimap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - or - exists(string left, string right | - left = "Field[ratpack.func.Pair.left]" and - right = "Field[ratpack.func.Pair.right]" - | - row = - ["ratpack.util;", "ratpack.func;"] + "Pair;true;" + - [ - "of;;;Argument[0];ReturnValue." + left + ";value;manual", - "of;;;Argument[1];ReturnValue." + right + ";value;manual", - "pair;;;Argument[0];ReturnValue." + left + ";value;manual", - "pair;;;Argument[1];ReturnValue." + right + ";value;manual", - "left;();;Argument[-1]." + left + ";ReturnValue;value;manual", - "right;();;Argument[-1]." + right + ";ReturnValue;value;manual", - "getLeft;;;Argument[-1]." + left + ";ReturnValue;value;manual", - "getRight;;;Argument[-1]." + right + ";ReturnValue;value;manual", - "left;(Object);;Argument[0];ReturnValue." + left + ";value;manual", - "left;(Object);;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - "right;(Object);;Argument[0];ReturnValue." + right + ";value;manual", - "right;(Object);;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "pushLeft;(Object);;Argument[-1];ReturnValue." + right + ";value;manual", - "pushRight;(Object);;Argument[-1];ReturnValue." + left + ";value;manual", - "pushLeft;(Object);;Argument[0];ReturnValue." + left + ";value;manual", - "pushRight;(Object);;Argument[0];ReturnValue." + right + ";value;manual", - // `nestLeft` Pair.nestLeft(C) -> Pair, B> - "nestLeft;(Object);;Argument[0];ReturnValue." + left + "." + left + ";value;manual", - "nestLeft;(Object);;Argument[-1]." + left + ";ReturnValue." + left + "." + right + - ";value;manual", - "nestLeft;(Object);;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - // `nestRight` Pair.nestRight(C) -> Pair> - "nestRight;(Object);;Argument[0];ReturnValue." + right + "." + left + ";value;manual", - "nestRight;(Object);;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "nestRight;(Object);;Argument[-1]." + right + ";ReturnValue." + right + "." + right + - ";value;manual", - // `mapLeft` & `mapRight` map over their respective fields - "mapLeft;;;Argument[-1]." + left + ";Argument[0].Parameter[0];value;manual", - "mapLeft;;;Argument[-1]." + right + ";ReturnValue." + right + ";value;manual", - "mapRight;;;Argument[-1]." + right + ";Argument[0].Parameter[0];value;manual", - "mapRight;;;Argument[-1]." + left + ";ReturnValue." + left + ";value;manual", - "mapLeft;;;Argument[0].ReturnValue;ReturnValue." + left + ";value;manual", - "mapRight;;;Argument[0].ReturnValue;ReturnValue." + right + ";value;manual", - // `map` maps over the `Pair` - "map;;;Argument[-1];Argument[0].Parameter[0];value;manual", - "map;;;Argument[0].ReturnValue;ReturnValue;value;manual" - ] - ) - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll b/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll index 8f619d4a104..7efa72c3164 100644 --- a/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll +++ b/java/ql/lib/semmle/code/java/frameworks/ratpack/RatpackExec.qll @@ -5,103 +5,6 @@ import java private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.FlowSteps -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Model for Ratpack `Promise` methods. - */ -private class RatpackExecModel extends SummaryModelCsv { - override predicate row(string row) { - //"namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind", - row = - "ratpack.exec;Promise;true;" + - [ - // `Promise` creation methods - "value;;;Argument[0];ReturnValue.Element;value;manual", - "flatten;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "sync;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - // `Promise` value transformation methods - "map;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "map;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "blockingMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "blockingMap;;;Argument[0].ReturnValue;ReturnValue.Element;value;manual", - "mapError;;;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - // `apply` passes the qualifier to the function as the first argument - "apply;;;Argument[-1].Element;Argument[0].Parameter[0].Element;value;manual", - "apply;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - // `Promise` termination method - "then;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // 'next' accesses qualifier the 'Promise' value and also returns the qualifier - "next;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "nextOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // `nextOpIf` accesses qualifier the 'Promise' value and also returns the qualifier - "nextOpIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "nextOpIf;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - // 'cacheIf' accesses qualifier the 'Promise' value and also returns the qualifier - "cacheIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // 'route' accesses qualifier the 'Promise' value, and conditionally returns the qualifier or - // the result of the second argument - "route;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "route;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - "route;;;Argument[-1];ReturnValue;value;manual", - // `flatMap` type methods return their returned `Promise` - "flatMap;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatMap;;;Argument[0].ReturnValue.Element;ReturnValue.Element;value;manual", - "flatMapError;;;Argument[1].ReturnValue.Element;ReturnValue.Element;value;manual", - // `blockingOp` passes the value to the argument - "blockingOp;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - // `replace` returns the passed `Promise` - "replace;;;Argument[0].Element;ReturnValue.Element;value;manual", - // `mapIf` methods conditionally map their values, or return themselves - "mapIf;;;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "mapIf;;;Argument[-1].Element;Argument[1].Parameter[0];value;manual", - "mapIf;;;Argument[-1].Element;Argument[2].Parameter[0];value;manual", - "mapIf;;;Argument[1].ReturnValue;ReturnValue.Element;value;manual", - "mapIf;;;Argument[2].ReturnValue;ReturnValue.Element;value;manual", - // `wiretap` wraps the qualifier `Promise` value in a `Result` and passes it to the argument - "wiretap;;;Argument[-1].Element;Argument[0].Parameter[0].Element;value;manual" - ] - or - exists(string left, string right | - left = "Field[ratpack.func.Pair.left]" and - right = "Field[ratpack.func.Pair.right]" - | - row = - "ratpack.exec;Promise;true;" + - [ - // `left`, `right`, `flatLeft`, `flatRight` all pass the qualifier `Promise` element as the other `Pair` field - "left;;;Argument[-1].Element;ReturnValue.Element." + right + ";value;manual", - "right;;;Argument[-1].Element;ReturnValue.Element." + left + ";value;manual", - "flatLeft;;;Argument[-1].Element;ReturnValue.Element." + right + ";value;manual", - "flatRight;;;Argument[-1].Element;ReturnValue.Element." + left + ";value;manual", - // `left` and `right` taking a `Promise` create a `Promise` of the `Pair` - "left;(Promise);;Argument[0].Element;ReturnValue.Element." + left + ";value;manual", - "right;(Promise);;Argument[0].Element;ReturnValue.Element." + right + ";value;manual", - // `left` and `right` taking a `Function` pass the qualifier element then create a `Pair` with the returned value - "left;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatLeft;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "right;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "flatRight;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;manual", - "left;(Function);;Argument[0].ReturnValue;ReturnValue.Element." + left + ";value;manual", - "flatLeft;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element." + left + - ";value;manual", - "right;(Function);;Argument[0].ReturnValue;ReturnValue.Element." + right + - ";value;manual", - "flatRight;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element." + right + - ";value;manual" - ] - ) - or - row = - "ratpack.exec;Result;true;" + - [ - "success;;;Argument[0];ReturnValue.Element;value;manual", - "getValue;;;Argument[-1].Element;ReturnValue;value;manual", - "getValueOrThrow;;;Argument[-1].Element;ReturnValue;value;manual" - ] - } -} /** A reference type that extends a parameterization the Promise type. */ private class RatpackPromise extends RefType { diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll b/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll index fd3008e5f00..2b09288610e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/Spring.qll @@ -6,14 +6,10 @@ import semmle.code.java.frameworks.spring.SpringAttribute import semmle.code.java.frameworks.spring.SpringAutowire import semmle.code.java.frameworks.spring.SpringBean import semmle.code.java.frameworks.spring.SpringBeanFile -import semmle.code.java.frameworks.spring.SpringBeans import semmle.code.java.frameworks.spring.SpringBeanRefType -import semmle.code.java.frameworks.spring.SpringCache -import semmle.code.java.frameworks.spring.SpringContext import semmle.code.java.frameworks.spring.SpringComponentScan import semmle.code.java.frameworks.spring.SpringConstructorArg import semmle.code.java.frameworks.spring.SpringController -import semmle.code.java.frameworks.spring.SpringData import semmle.code.java.frameworks.spring.SpringDescription import semmle.code.java.frameworks.spring.SpringEntry import semmle.code.java.frameworks.spring.SpringFlex @@ -36,12 +32,7 @@ import semmle.code.java.frameworks.spring.SpringQualifier import semmle.code.java.frameworks.spring.SpringRef import semmle.code.java.frameworks.spring.SpringReplacedMethod import semmle.code.java.frameworks.spring.SpringSet -import semmle.code.java.frameworks.spring.SpringUi -import semmle.code.java.frameworks.spring.SpringUtil -import semmle.code.java.frameworks.spring.SpringValidation import semmle.code.java.frameworks.spring.SpringValue -import semmle.code.java.frameworks.spring.SpringWebMultipart -import semmle.code.java.frameworks.spring.SpringWebUtil import semmle.code.java.frameworks.spring.SpringXMLElement import semmle.code.java.frameworks.spring.metrics.MetricSpringBean import semmle.code.java.frameworks.spring.metrics.MetricSpringBeanFile diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll deleted file mode 100644 index 63671f21855..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Provides classes and predicates for working with Spring classes and interfaces from - * `org.springframework.beans`. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Provides models for the `org.springframework.beans` package. - */ -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue);;Argument[0];Argument[-1];value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.beans;PropertyValue;false;getName;;;Argument[-1].MapKey;ReturnValue;value;manual", - "org.springframework.beans;PropertyValue;false;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.beans;PropertyValues;true;getPropertyValue;;;Argument[-1].Element;ReturnValue;value;manual", - "org.springframework.beans;PropertyValues;true;getPropertyValues;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(List);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapKey;Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapValue;Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(PropertyValues);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[0];Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[0].MapKey;Argument[-1].Element.MapKey;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[0].MapValue;Argument[-1].Element.MapValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[-1];ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;get;;;Argument[-1].Element.MapValue;ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValue;;;Argument[-1].Element;ReturnValue;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValueList;;;Argument[-1].Element;ReturnValue.Element;value;manual", - "org.springframework.beans;MutablePropertyValues;true;getPropertyValues;;;Argument[-1].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.beans;MutablePropertyValues;true;setPropertyValueAt;;;Argument[0];Argument[-1].Element;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll deleted file mode 100644 index 007ce0d9d71..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCache.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides models for the `org.springframework.cache` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.cache;Cache$ValueRetrievalException;false;ValueRetrievalException;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache$ValueRetrievalException;false;getKey;;;Argument[-1].MapKey;ReturnValue;value;manual", - "org.springframework.cache;Cache$ValueWrapper;true;get;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object,Callable);;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;get;(Object,Class);;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.cache;Cache;true;getNativeCache;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.cache;Cache;true;getNativeCache;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.cache;Cache;true;put;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache;true;put;;;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.cache;Cache;true;putIfAbsent;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll deleted file mode 100644 index 3860a5457cd..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringContext.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Provides models for the `org.springframework.context` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class StringSummaryCsv extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],String,Locale);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],String,Locale);;Argument[2];ReturnValue;taint;manual", - "org.springframework.context;MessageSource;true;getMessage;(String,Object[],Locale);;Argument[1].ArrayElement;ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll deleted file mode 100644 index 52c8579b4c7..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringData.qll +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Provides classes and predicates for working with Spring classes and interfaces from - * `org.springframework.data`. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -/** - * Provides models for the `org.springframework.data` package. - */ -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - "org.springframework.data.repository;CrudRepository;true;save;;;Argument[0];ReturnValue;value;manual" - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll index 2114b4fcc75..4e91c1f18a2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll @@ -4,7 +4,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.frameworks.spring.SpringController private import semmle.code.java.security.XSS as XSS @@ -43,107 +42,6 @@ class SpringHttpHeaders extends Class { SpringHttpHeaders() { this.hasQualifiedName("org.springframework.http", "HttpHeaders") } } -private class UrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.http;RequestEntity;false;get;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;post;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;head;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;delete;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;options;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;patch;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;put;;;Argument[0];open-url;manual", - "org.springframework.http;RequestEntity;false;method;;;Argument[1];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(HttpMethod,URI);;Argument[1];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(MultiValueMap,HttpMethod,URI);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI,Type);;Argument[2];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI);;Argument[3];open-url;manual", - "org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI,Type);;Argument[3];open-url;manual" - ] - } -} - -private class SpringHttpFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpEntity;true;getBody;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpEntity;true;getHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,HttpStatus);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[1].MapKey;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[1].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity;true;of;(Optional);;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;ok;(Object);;Argument[0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity;true;created;(URI);;Argument[0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;contentLength;(long);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;contentType;(MediaType);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$BodyBuilder;true;body;(Object);;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;allow;(HttpMethod[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(Consumer);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;lastModified;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;varyBy;(String[]);;Argument[-1];ReturnValue;value;manual", - "org.springframework.http;ResponseEntity$HeadersBuilder;true;build;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;RequestEntity;true;getUrl;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;get;(Object);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlAllowHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlAllowOrigin;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlExposeHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getAccessControlRequestHeaders;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getCacheControl;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getConnection;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getETag;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getETagValuesAsList;(String);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getFieldValues;(String);;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getFirst;(String);;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getIfMatch;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getIfNoneMatch;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getHost;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getLocation;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getOrEmpty;(Object);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getOrigin;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getPragma;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getUpgrade;();;Argument[-1];ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;getValuesAsList;(String);;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;getVary;();;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.http;HttpHeaders;true;add;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;set;(String,String);;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(String,List);;Argument[0];Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;addAll;(String,List);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;Argument[0].MapKey;ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;Argument[0].MapValue.Element;ReturnValue;taint;manual", - "org.springframework.http;HttpHeaders;true;encodeBasicAuth;(String,String,Charset);;Argument[0..1];ReturnValue;taint;manual" - ] - } -} - private predicate specifiesContentType(SpringRequestMappingMethod method) { exists(method.getAProducesExpr()) } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll index 7f284b0771f..48a2b367990 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringProfile.qll @@ -73,9 +73,8 @@ abstract class AlwaysEnabledSpringProfile extends string { * * Includes all `SpringProfile`s that are not specified as always enabled or never enabled. */ -class SometimesEnabledSpringProfile extends string { +class SometimesEnabledSpringProfile extends string instanceof SpringProfile { SometimesEnabledSpringProfile() { - this instanceof SpringProfile and not ( this instanceof AlwaysEnabledSpringProfile or this instanceof NeverEnabledSpringProfile diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll deleted file mode 100644 index e8ade8aa432..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUi.qll +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Provides models for the `org.springframework.ui` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.ui;Model;true;addAllAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Collection);;Argument[0].Element;Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;addAllAttributes;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;Model;true;asMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.ui;Model;true;asMap;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.ui;Model;true;getAttribute;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;Model;true;mergeAttributes;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Collection);;Argument[0].Element;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ModelMap;false;getAttribute;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(Object);;Argument[0];Argument[-1].MapValue;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[1];Argument[-1].MapValue;value;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll deleted file mode 100644 index 7c78c6b7afc..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringUtil.qll +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Provides models for the `org.springframework.util` package. - */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.util;AntPathMatcher;false;combine;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;doMatch;;;Argument[1];Argument[3].MapValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;extractPathWithinPattern;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;extractUriTemplateVariables;;;Argument[1];ReturnValue.MapValue;taint;manual", - "org.springframework.util;AntPathMatcher;false;tokenizePath;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;AntPathMatcher;false;tokenizePattern;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,org.springframework.util.AutoPopulatingList.ElementFactory);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,java.lang.Class);;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;Base64Utils;false;decode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeFromString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeFromUrlSafeString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;decodeUrlSafe;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeToUrlSafeString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;Base64Utils;false;encodeUrlSafe;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;CollectionUtils;false;arrayToList;;;Argument[0].ArrayElement;ReturnValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;findFirstMatch;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;findValueOfType;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;firstElement;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;lastElement;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;CollectionUtils;false;mergeArrayIntoCollection;;;Argument[0].ArrayElement;Argument[1].Element;value;manual", - "org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;Argument[0].MapKey;Argument[1].MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;Argument[0].MapValue;Argument[1].MapValue;value;manual", - "org.springframework.util;CollectionUtils;false;toArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;CollectionUtils;false;toIterator;;;Argument[0].Element;ReturnValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;toMultiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;toMultiValueMap;;;Argument[0].MapValue.Element;ReturnValue.MapValue.Element;value;manual", - "org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;CompositeIterator;false;add;;;Argument[0].Element;Argument[-1].Element;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;FastByteArrayOutputStream;false;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;write;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.util;FastByteArrayOutputStream;false;writeTo;;;Argument[-1];Argument[0];taint;manual", - "org.springframework.util;FileCopyUtils;false;copy;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;FileCopyUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;FileCopyUtils;false;copyToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;FileSystemUtils;false;copyRecursively;(java.io.File,java.io.File);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", - "org.springframework.util;MultiValueMap;true;add;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;add;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Argument[1].Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;getFirst;;;Argument[-1].MapValue.Element;ReturnValue;value;manual", - "org.springframework.util;MultiValueMap;true;set;;;Argument[0];Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;set;;;Argument[1];Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;setAll;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;setAll;;;Argument[0].MapValue;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;MultiValueMap;true;toSingleValueMap;;;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.util;MultiValueMap;true;toSingleValueMap;;;Argument[-1].MapValue.Element;ReturnValue.MapValue;value;manual", - "org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual", - "org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;Argument[0].MapValue.Element;Argument[-1].MapValue.Element;value;manual", - "org.springframework.util;ObjectUtils;false;addObjectToArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;addObjectToArray;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;toObjectArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;ObjectUtils;false;unwrapOptional;;;Argument[0].Element;ReturnValue;value;manual", - "org.springframework.util;PropertiesPersister;true;load;;;Argument[1];Argument[0];taint;manual", - "org.springframework.util;PropertiesPersister;true;loadFromXml;;;Argument[1];Argument[0];taint;manual", - "org.springframework.util;PropertiesPersister;true;store;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;store;;;Argument[2];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[2];Argument[1];taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;PropertyPlaceholderHelper;;;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;parseStringValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;(java.lang.String,java.util.Properties);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;extractArchiveURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;extractJarFileURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;getFile;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;getURL;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;ResourceUtils;false;toURI;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;RouteMatcher;true;combine;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[1];ReturnValue.MapValue;taint;manual", - "org.springframework.util;RouteMatcher;true;parseRoute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SerializationUtils;false;deserialize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SerializationUtils;false;serialize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StreamUtils;false;copy;(byte[],java.io.OutputStream);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copy;(java.io.InputStream,java.io.OutputStream);;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copy;(java.lang.String,java.nio.charset.Charset,java.io.OutputStream);;Argument[0];Argument[2];taint;manual", - "org.springframework.util;StreamUtils;false;copyRange;;;Argument[0];Argument[1];taint;manual", - "org.springframework.util;StreamUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StreamUtils;false;copyToString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;addStringToArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;addStringToArray;;;Argument[1];ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;applyRelativePath;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToCommaDelimitedString;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToDelimitedString;;;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;arrayToDelimitedString;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;capitalize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;cleanPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToCommaDelimitedString;;;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Argument[0].Element;ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Argument[1..3];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;commaDelimitedListToSet;;;Argument[0];ReturnValue.Element;taint;manual", - "org.springframework.util;StringUtils;false;commaDelimitedListToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;concatenateStringArrays;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;delete;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;deleteAny;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;delimitedListToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;getFilename;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;getFilenameExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;mergeStringArrays;;;Argument[0..1].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;quote;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;quoteIfString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;removeDuplicateStrings;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;replace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;replace;;;Argument[2];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;sortStringArray;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;split;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;Argument[0].ArrayElement;ReturnValue.MapKey;taint;manual", - "org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;Argument[0].ArrayElement;ReturnValue.MapValue;taint;manual", - "org.springframework.util;StringUtils;false;stripFilenameExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;tokenizeToStringArray;;;Argument[0];ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;toStringArray;;;Argument[0].Element;ReturnValue.ArrayElement;value;manual", - "org.springframework.util;StringUtils;false;trimAllWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimArrayElements;;;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.util;StringUtils;false;trimLeadingCharacter;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimLeadingWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimTrailingCharacter;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimTrailingWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;trimWhitespace;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;uncapitalize;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;unqualify;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringUtils;false;uriDecode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;StringValueResolver;false;resolveStringValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.util;SystemPropertyUtils;false;resolvePlaceholders;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll deleted file mode 100644 index 2dcf184de84..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringValidation.qll +++ /dev/null @@ -1,25 +0,0 @@ -/** Definitions of flow steps through utility methods of `org.springframework.validation.Errors`. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class SpringValidationErrorModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.validation;Errors;true;addAllErrors;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;getAllErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getFieldError;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getFieldErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getGlobalError;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;getGlobalErrors;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;reject;;;Argument[2];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;;;Argument[1];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;;;Argument[3];Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.Object[],java.lang.String);;Argument[2].ArrayElement;Argument[-1];taint;manual", - "org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];Argument[-1];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index 9744c323e36..3a8d4bb084a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -4,7 +4,6 @@ import java import SpringHttp -private import semmle.code.java.dataflow.ExternalFlow /** The class `org.springframework.web.client.RestTemplate`. */ class SpringRestTemplate extends Class { @@ -28,26 +27,3 @@ class SpringWebClient extends Interface { this.hasQualifiedName("org.springframework.web.reactive.function.client", "WebClient") } } - -private class UrlOpenSink extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.client;RestTemplate;false;delete;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;doExecute;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;exchange;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;execute;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;getForEntity;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;getForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;headForHeaders;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;optionsForAllow;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;patchForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForEntity;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForLocation;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;postForObject;;;Argument[0];open-url;manual", - "org.springframework.web.client;RestTemplate;false;put;;;Argument[0];open-url;manual", - "org.springframework.web.reactive.function.client;WebClient;false;create;;;Argument[0];open-url;manual", - "org.springframework.web.reactive.function.client;WebClient$Builder;false;baseUrl;;;Argument[0];open-url;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll deleted file mode 100644 index 43acaceda76..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebMultipart.qll +++ /dev/null @@ -1,25 +0,0 @@ -/** Provides models of taint flow in `org.springframework.web.multipart` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.multipart;MultipartFile;true;getBytes;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getName;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getOriginalFilename;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartFile;true;getResource;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartHttpServletRequest;true;getMultipartHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartHttpServletRequest;true;getRequestHeaders;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFile;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFileNames;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getFiles;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.multipart;MultipartRequest;true;getMultiFileMap;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.multipart;MultipartResolver;true;resolveMultipart;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll deleted file mode 100644 index 4f855eedbae..00000000000 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebUtil.qll +++ /dev/null @@ -1,176 +0,0 @@ -/** Provides models of taint flow in `org.springframework.web.util` */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class FlowSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.web.util;UriBuilder;true;build;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Map);;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;build;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilder;true;fragment;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;fragment;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;host;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;host;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;path;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;path;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;pathSegment;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;pathSegment;;;Argument[0].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;port;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;port;(java.lang.String);;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;query;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;query;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParam;(String,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParamIfPresent;;;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;queryParams;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replacePath;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replacePath;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQuery;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQuery;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;(String,Collection);;Argument[1].Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParam;(String,Object[]);;Argument[1].ArrayElement;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[0].MapKey;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;replaceQueryParams;;;Argument[0].MapValue.Element;Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;scheme;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;scheme;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilder;true;userInfo;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriBuilder;true;userInfo;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriBuilderFactory;true;builder;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriBuilderFactory;true;uriString;;;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents$UriTemplateVariables;true;getValue;;;Argument[-1].MapValue;ReturnValue;value;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;;;Argument[-1..0];ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;(String,Map);;Argument[1].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplateHandler;true;expand;(String,Object[]);;Argument[1].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;getBaseUrl;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;setBaseUrl;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;AbstractUriTemplateHandler;true;setDefaultUriVariables;;;Argument[0];Argument[-1];taint;manual", - // writing to a `Request` or `Response` currently doesn't propagate taint to the object itself. - "org.springframework.web.util;ContentCachingRequestWrapper;false;ContentCachingRequestWrapper;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;ContentCachingRequestWrapper;false;getContentAsByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;ContentCachingResponseWrapper;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;getContentAsByteArray;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;ContentCachingResponseWrapper;false;getContentInputStream;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;DefaultUriBuilderFactory;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;builder;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;getDefaultUriVariables;;;Argument[-1];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;setDefaultUriVariables;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;DefaultUriBuilderFactory;false;uriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscape;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscapeDecimal;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlEscapeHex;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;HtmlUtils;false;htmlUnescape;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletContextPropertyUtils;false;resolvePlaceholders;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getCachedPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getCachedPathValue;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;getParsedRequestPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;parseAndCache;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;ServletRequestPathUtils;false;setParsedRequestPath;;;Argument[0];Argument[1];taint;manual", - "org.springframework.web.util;UriComponents;false;UriComponents;;;Argument[0..1];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponents;false;copyToUriComponentsBuilder;;;Argument[-1];Argument[0];taint;manual", - "org.springframework.web.util;UriComponents;false;encode;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;expand;(UriTemplateVariables);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getFragment;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getHost;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getPath;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getPathSegments;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getQuery;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getQueryParams;;;Argument[-1];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriComponents;false;getQueryParams;;;Argument[-1];ReturnValue.MapValue.Element;taint;manual", - "org.springframework.web.util;UriComponents;false;getScheme;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getSchemeSpecificPart;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;getUserInfo;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toUri;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toUriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponents;false;normalize;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;build;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;buildAndExpand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;buildAndExpand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;cloneBuilder;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;encode;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromHttpRequest;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromHttpUrl;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromOriginHeader;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;fromUriString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;parseForwardedFor;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;schemeSpecificPart;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;schemeSpecificPart;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;toUriString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uri;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uri;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriComponents;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriComponents;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriVariables;;;Argument[-1];ReturnValue;value;manual", - "org.springframework.web.util;UriComponentsBuilder;false;uriVariables;;;Argument[0].MapValue;Argument[-1];taint;manual", - "org.springframework.web.util;UriTemplate;false;expand;(Map);;Argument[0].MapValue;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;expand;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;getVariableNames;;;Argument[-1];ReturnValue.Element;taint;manual", - "org.springframework.web.util;UriTemplate;false;match;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriTemplate;false;toString;;;Argument[-1];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;decode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encode;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeAuthority;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeFragment;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeHost;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePathSegment;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodePort;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQuery;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParam;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParams;;;Argument[0].MapKey;ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeQueryParams;;;Argument[0].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeScheme;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Map);;Argument[0].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Map);;Argument[0].MapKey;ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUriVariables;(Object[]);;Argument[0].ArrayElement;ReturnValue.ArrayElement;taint;manual", - "org.springframework.web.util;UriUtils;false;encodeUserInfo;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UriUtils;false;extractFileExtension;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeMatrixVariables;;;Argument[1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeMatrixVariables;;;Argument[1].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodePathVariables;;;Argument[1].MapKey;ReturnValue.MapKey;value;manual", - "org.springframework.web.util;UrlPathHelper;false;decodePathVariables;;;Argument[1].MapValue;ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;decodeRequestString;;;Argument[1];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getContextPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingContextPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingQueryString;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getOriginatingRequestUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getPathWithinApplication;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getPathWithinServletMapping;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getRequestUri;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getResolvedLookupPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;getServletPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;removeSemicolonContent;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;UrlPathHelper;false;resolveAndCacheLookupPath;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;findParameterValue;(Map,String);;Argument[0].MapValue;ReturnValue;value;manual", - "org.springframework.web.util;WebUtils;false;findParameterValue;(ServletRequest,String);;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getCookie;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getNativeRequest;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getNativeResponse;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getParametersStartingWith;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;WebUtils;false;getParametersStartingWith;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getRealPath;;;Argument[0..1];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getRequiredSessionAttribute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;getSessionAttribute;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.web.util;WebUtils;false;parseMatrixVariables;;;Argument[0];ReturnValue.MapKey;taint;manual", - "org.springframework.web.util;WebUtils;false;parseMatrixVariables;;;Argument[0];ReturnValue.MapValue;taint;manual", - "org.springframework.web.util;WebUtils;false;setSessionAttribute;;;Argument[2];Argument[0];taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index 8936de5a923..5a913ccdef8 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -6,7 +6,6 @@ import java import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.DataFlow2 -private import RegexFlowModels private import semmle.code.java.security.SecurityTests private class ExploitableStringLiteral extends StringLiteral { diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll deleted file mode 100644 index de0b5465fe4..00000000000 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll +++ /dev/null @@ -1,32 +0,0 @@ -/** Definitions of data flow steps for determining flow of regular expressions. */ - -import java -import semmle.code.java.dataflow.ExternalFlow - -private class RegexSinkCsv extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //"namespace;type;subtypes;name;signature;ext;input;kind" - "java.util.regex;Matcher;false;matches;();;Argument[-1];regex-use[f];manual", - "java.util.regex;Pattern;false;asMatchPredicate;();;Argument[-1];regex-use[f];manual", - "java.util.regex;Pattern;false;compile;(String);;Argument[0];regex-use[];manual", - "java.util.regex;Pattern;false;compile;(String,int);;Argument[0];regex-use[];manual", - "java.util.regex;Pattern;false;matcher;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;matches;(String,CharSequence);;Argument[0];regex-use[f1];manual", - "java.util.regex;Pattern;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;split;(CharSequence,int);;Argument[-1];regex-use[0];manual", - "java.util.regex;Pattern;false;splitAsStream;(CharSequence);;Argument[-1];regex-use[0];manual", - "java.util.function;Predicate;false;test;(Object);;Argument[-1];regex-use[0];manual", - "java.lang;String;false;matches;(String);;Argument[0];regex-use[f-1];manual", - "java.lang;String;false;split;(String);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;split;(String,int);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;replaceAll;(String,String);;Argument[0];regex-use[-1];manual", - "java.lang;String;false;replaceFirst;(String,String);;Argument[0];regex-use[-1];manual", - "com.google.common.base;Splitter;false;onPattern;(String);;Argument[0];regex-use[];manual", - "com.google.common.base;Splitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - "com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[-1];regex-use[0];manual", - "com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual", - ] - } -} diff --git a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll index 14663327103..cb770ffe48a 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexTreeView.qll @@ -1,7 +1,19 @@ /** Provides a class hierarchy corresponding to a parse tree of regular expressions. */ -private import java -private import semmle.code.java.regex.regex +private import semmle.code.java.regex.regex as RE // importing under a namescape to avoid naming conflict for `Top`. +private import codeql.regex.nfa.NfaUtils as NfaUtils +// exporting as RegexTreeView, and in the top-level scope. +import Impl as RegexTreeView +import Impl + +/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */ +RegExpTerm getParsedRegExp(RE::StringLiteral re) { result.getRegex() = re and result.isRootTerm() } + +private class Regex = RE::Regex; + +private class Location = RE::Location; + +private class File = RE::File; /** * An element containing a regular expression term, that is, either @@ -49,1038 +61,1153 @@ private newtype TRegExpParent = /** A back reference */ TRegExpBackRef(Regex re, int start, int end) { re.backreference(start, end) } -/** - * An element containing a regular expression term, that is, either - * a string literal (parsed as a regular expression; the root of the parse tree) - * or another regular expression term (a descendant of the root). - */ -class RegExpParent extends TRegExpParent { - /** Gets a textual representation of this element. */ - string toString() { result = "RegExpParent" } +private import codeql.regex.RegexTreeView - /** Gets the `i`th child term. */ - RegExpTerm getChild(int i) { none() } +/** An implementation that statisfies the RegexTreeView signature. */ +module Impl implements RegexTreeViewSig { + /** + * An element containing a regular expression term, that is, either + * a string literal (parsed as a regular expression; the root of the parse tree) + * or another regular expression term (a descendant of the root). + */ + class RegExpParent extends TRegExpParent { + /** Gets a textual representation of this element. */ + string toString() { result = "RegExpParent" } - /** Gets a child term . */ - RegExpTerm getAChild() { result = this.getChild(_) } + /** Gets the `i`th child term. */ + RegExpTerm getChild(int i) { none() } - /** Gets the number of child terms. */ - int getNumChild() { result = count(this.getAChild()) } + /** Gets a child term . */ + RegExpTerm getAChild() { result = this.getChild(_) } - /** Gets the associated regex. */ - abstract Regex getRegex(); -} + /** Gets the number of child terms. */ + int getNumChild() { result = count(this.getAChild()) } -/** - * A string literal used as a regular expression. - * - * As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`) - * and therefore may be relevant for ReDoS queries are considered. - */ -class RegExpLiteral extends TRegExpLiteral, RegExpParent { - Regex re; + /** Gets the associated regex. */ + abstract Regex getRegex(); - RegExpLiteral() { this = TRegExpLiteral(re) } - - override string toString() { result = re.toString() } - - override RegExpTerm getChild(int i) { i = 0 and result.getRegex() = re and result.isRootTerm() } - - /** Holds if dot, `.`, matches all characters, including newlines. */ - predicate isDotAll() { re.getAMode() = "DOTALL" } - - /** Holds if this regex matching is case-insensitive for this regex. */ - predicate isIgnoreCase() { re.getAMode() = "IGNORECASE" } - - /** Get a string representing all modes for this regex. */ - string getFlags() { result = concat(string mode | mode = re.getAMode() | mode, " | ") } - - override Regex getRegex() { result = re } - - /** Gets the primary QL class for this regex. */ - string getPrimaryQLClass() { result = "RegExpLiteral" } -} - -/** - * A regular expression term, that is, a syntactic part of a regular expression. - * These are the tree nodes that form the parse tree of a regular expression literal. - */ -class RegExpTerm extends RegExpParent { - Regex re; - int start; - int end; - - RegExpTerm() { - this = TRegExpAlt(re, start, end) - or - this = TRegExpBackRef(re, start, end) - or - this = TRegExpCharacterClass(re, start, end) - or - this = TRegExpCharacterRange(re, start, end) - or - this = TRegExpNormalChar(re, start, end) - or - this = TRegExpQuote(re, start, end) - or - this = TRegExpGroup(re, start, end) - or - this = TRegExpQuantifier(re, start, end) - or - this = TRegExpSequence(re, start, end) - or - this = TRegExpSpecialChar(re, start, end) + /** Gets the last child term of this element. */ + RegExpTerm getLastChild() { result = this.getChild(this.getNumChild() - 1) } } /** - * Gets the outermost term of this regular expression. + * A string literal used as a regular expression. + * + * As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`) + * and therefore may be relevant for ReDoS queries are considered. */ - RegExpTerm getRootTerm() { - this.isRootTerm() and result = this - or - result = this.getParent().(RegExpTerm).getRootTerm() + class RegExpLiteral extends TRegExpLiteral, RegExpParent { + Regex re; + + RegExpLiteral() { this = TRegExpLiteral(re) } + + override string toString() { result = re.toString() } + + override RegExpTerm getChild(int i) { i = 0 and result.getRegex() = re and result.isRootTerm() } + + /** Holds if dot, `.`, matches all characters, including newlines. */ + predicate isDotAll() { re.getAMode() = "DOTALL" } + + /** Holds if this regex matching is case-insensitive for this regex. */ + predicate isIgnoreCase() { re.getAMode() = "IGNORECASE" } + + /** Get a string representing all modes for this regex. */ + string getFlags() { result = concat(string mode | mode = re.getAMode() | mode, " | ") } + + override Regex getRegex() { result = re } + + /** Gets the primary QL class for this regex. */ + string getPrimaryQLClass() { result = "RegExpLiteral" } } /** - * Holds if this term is part of a string literal - * that is interpreted as a regular expression. + * A regular expression term, that is, a syntactic part of a regular expression. + * These are the tree nodes that form the parse tree of a regular expression literal. */ - predicate isUsedAsRegExp() { any() } + class RegExpTerm extends RegExpParent { + Regex re; + int start; + int end; - /** - * Holds if this is the root term of a regular expression. - */ - predicate isRootTerm() { start = 0 and end = re.getText().length() } + RegExpTerm() { + this = TRegExpAlt(re, start, end) + or + this = TRegExpBackRef(re, start, end) + or + this = TRegExpCharacterClass(re, start, end) + or + this = TRegExpCharacterRange(re, start, end) + or + this = TRegExpNormalChar(re, start, end) + or + this = TRegExpQuote(re, start, end) + or + this = TRegExpGroup(re, start, end) + or + this = TRegExpQuantifier(re, start, end) + or + this = TRegExpSequence(re, start, end) + or + this = TRegExpSpecialChar(re, start, end) + } - /** - * Gets the parent term of this regular expression term, or the - * regular expression literal if this is the root term. - */ - RegExpParent getParent() { result.getAChild() = this } - - override Regex getRegex() { result = re } - - /** Gets the offset at which this term starts. */ - int getStart() { result = start } - - /** Gets the offset at which this term ends. */ - int getEnd() { result = end } - - /** Holds if this term occurs in regex `inRe` offsets `startOffset` to `endOffset`. */ - predicate occursInRegex(Regex inRe, int startOffset, int endOffset) { - inRe = re and startOffset = start and endOffset = end - } - - override string toString() { result = re.getText().substring(start, end) } - - /** - * Gets the location of the surrounding regex, as locations inside the regex do not exist. - * To get location information corresponding to the term inside the regex, - * use `hasLocationInfo`. - */ - Location getLocation() { result = re.getLocation() } - - /** Holds if this term is found at the specified location offsets. */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - /* - * This is an approximation that handles the simple and common case of single, - * normal string literal written in the source, but does not give correct results in more complex cases - * such as compile-time concatenation, or multi-line string literals. + /** + * Gets the outermost term of this regular expression. */ - - exists(int re_start, int re_end, int src_start, int src_end | - re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, re_end) and - re.sourceCharacter(start, src_start, _) and - re.sourceCharacter(end - 1, _, src_end) and - startcolumn = re_start + src_start and - endcolumn = re_start + src_end - 1 - ) - } - - /** Gets the file in which this term is found. */ - File getFile() { result = this.getLocation().getFile() } - - /** Gets the raw source text of this term. */ - string getRawValue() { result = this.toString() } - - /** Gets the string literal in which this term is found. */ - RegExpLiteral getLiteral() { result = TRegExpLiteral(re) } - - /** Gets the regular expression term that is matched (textually) before this one, if any. */ - RegExpTerm getPredecessor() { - exists(RegExpTerm parent | parent = this.getParent() | - result = parent.(RegExpSequence).previousElement(this) + RegExpTerm getRootTerm() { + this.isRootTerm() and result = this or - not exists(parent.(RegExpSequence).previousElement(this)) and - not parent instanceof RegExpSubPattern and - result = parent.getPredecessor() - ) + result = this.getParent().(RegExpTerm).getRootTerm() + } + + /** + * Holds if this term is part of a string literal + * that is interpreted as a regular expression. + */ + predicate isUsedAsRegExp() { any() } + + /** + * Holds if this is the root term of a regular expression. + */ + predicate isRootTerm() { start = 0 and end = re.getText().length() } + + /** + * Gets the parent term of this regular expression term, or the + * regular expression literal if this is the root term. + */ + RegExpParent getParent() { result.getAChild() = this } + + override Regex getRegex() { result = re } + + /** Gets the offset at which this term starts. */ + int getStart() { result = start } + + /** Gets the offset at which this term ends. */ + int getEnd() { result = end } + + /** Holds if this term occurs in regex `inRe` offsets `startOffset` to `endOffset`. */ + predicate occursInRegex(Regex inRe, int startOffset, int endOffset) { + inRe = re and startOffset = start and endOffset = end + } + + override string toString() { result = re.getText().substring(start, end) } + + /** + * Gets the location of the surrounding regex, as locations inside the regex do not exist. + * To get location information corresponding to the term inside the regex, + * use `hasLocationInfo`. + */ + Location getLocation() { result = re.getLocation() } + + /** Holds if this term is found at the specified location offsets. */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + /* + * This is an approximation that handles the simple and common case of single, + * normal string literal written in the source, but does not give correct results in more complex cases + * such as compile-time concatenation, or multi-line string literals. + */ + + exists(int re_start, int re_end, int src_start, int src_end | + re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, re_end) and + re.sourceCharacter(start, src_start, _) and + re.sourceCharacter(end - 1, _, src_end) and + startcolumn = re_start + src_start and + endcolumn = re_start + src_end - 1 + ) + } + + /** Gets the file in which this term is found. */ + File getFile() { result = this.getLocation().getFile() } + + /** Gets the raw source text of this term. */ + string getRawValue() { result = this.toString() } + + /** Gets the string literal in which this term is found. */ + RegExpLiteral getLiteral() { result = TRegExpLiteral(re) } + + /** Gets the regular expression term that is matched (textually) before this one, if any. */ + RegExpTerm getPredecessor() { + exists(RegExpTerm parent | parent = this.getParent() | + result = parent.(RegExpSequence).previousElement(this) + or + not exists(parent.(RegExpSequence).previousElement(this)) and + not parent instanceof RegExpSubPattern and + result = parent.getPredecessor() + ) + } + + /** Gets the regular expression term that is matched (textually) after this one, if any. */ + RegExpTerm getSuccessor() { + exists(RegExpTerm parent | parent = this.getParent() | + result = parent.(RegExpSequence).nextElement(this) + or + not exists(parent.(RegExpSequence).nextElement(this)) and + not parent instanceof RegExpSubPattern and + result = parent.getSuccessor() + ) + } + + /** Gets the primary QL class for this term. */ + string getPrimaryQLClass() { result = "RegExpTerm" } } - /** Gets the regular expression term that is matched (textually) after this one, if any. */ - RegExpTerm getSuccessor() { - exists(RegExpTerm parent | parent = this.getParent() | - result = parent.(RegExpSequence).nextElement(this) - or - not exists(parent.(RegExpSequence).nextElement(this)) and - not parent instanceof RegExpSubPattern and - result = parent.getSuccessor() - ) - } - - /** Gets the primary QL class for this term. */ - string getPrimaryQLClass() { result = "RegExpTerm" } -} - -/** - * A quantified regular expression term. - * - * Example: - * - * ``` - * ((ECMA|Java)[sS]cript)* - * ``` - */ -class RegExpQuantifier extends RegExpTerm, TRegExpQuantifier { - int part_end; - boolean maybe_empty; - boolean may_repeat_forever; - - RegExpQuantifier() { - this = TRegExpQuantifier(re, start, end) and - re.quantifiedPart(start, part_end, end, maybe_empty, may_repeat_forever) - } - - override RegExpTerm getChild(int i) { - i = 0 and - result.occursInRegex(re, start, part_end) - } - - /** Holds if this term may match zero times. */ - predicate mayBeEmpty() { maybe_empty = true } - - /** Holds if this term may match an unlimited number of times. */ - predicate mayRepeatForever() { may_repeat_forever = true } - - /** Gets the quantifier for this term. That is e.g "?" for "a?". */ - string getQuantifier() { result = re.getText().substring(part_end, end) } - - /** Holds if this is a possessive quantifier, e.g. a*+. */ - predicate isPossessive() { - exists(string q | q = this.getQuantifier() | q.length() > 1 and q.charAt(q.length() - 1) = "+") - } - - override string getPrimaryQLClass() { result = "RegExpQuantifier" } -} - -/** - * A regular expression term that permits unlimited repetitions. - */ -class InfiniteRepetitionQuantifier extends RegExpQuantifier { - InfiniteRepetitionQuantifier() { this.mayRepeatForever() } -} - -/** - * A star-quantified term. - * - * Example: - * - * ``` - * \w* - * ``` - */ -class RegExpStar extends InfiniteRepetitionQuantifier { - RegExpStar() { this.getQuantifier().charAt(0) = "*" } - - override string getPrimaryQLClass() { result = "RegExpStar" } -} - -/** - * A plus-quantified term. - * - * Example: - * - * ``` - * \w+ - * ``` - */ -class RegExpPlus extends InfiniteRepetitionQuantifier { - RegExpPlus() { this.getQuantifier().charAt(0) = "+" } - - override string getPrimaryQLClass() { result = "RegExpPlus" } -} - -/** - * An optional term. - * - * Example: - * - * ``` - * ;? - * ``` - */ -class RegExpOpt extends RegExpQuantifier { - RegExpOpt() { this.getQuantifier().charAt(0) = "?" } - - override string getPrimaryQLClass() { result = "RegExpOpt" } -} - -/** - * A range-quantified term - * - * Examples: - * - * ``` - * \w{2,4} - * \w{2,} - * \w{2} - * ``` - */ -class RegExpRange extends RegExpQuantifier { - string upper; - string lower; - - RegExpRange() { re.multiples(part_end, end, lower, upper) } - - /** Gets the string defining the upper bound of this range, which is empty when no such bound exists. */ - string getUpper() { result = upper } - - /** Gets the string defining the lower bound of this range, which is empty when no such bound exists. */ - string getLower() { result = lower } - /** - * Gets the upper bound of the range, if any. + * A quantified regular expression term. * - * If there is no upper bound, any number of repetitions is allowed. - * For a term of the form `r{lo}`, both the lower and the upper bound - * are `lo`. + * Example: + * + * ``` + * ((ECMA|Java)[sS]cript)* + * ``` */ - int getUpperBound() { result = this.getUpper().toInt() } + class RegExpQuantifier extends RegExpTerm, TRegExpQuantifier { + int part_end; + boolean maybe_empty; + boolean may_repeat_forever; - /** Gets the lower bound of the range. */ - int getLowerBound() { result = this.getLower().toInt() } + RegExpQuantifier() { + this = TRegExpQuantifier(re, start, end) and + re.quantifiedPart(start, part_end, end, maybe_empty, may_repeat_forever) + } - override string getPrimaryQLClass() { result = "RegExpRange" } -} - -/** - * A sequence term. - * - * Example: - * - * ``` - * (ECMA|Java)Script - * ``` - * - * This is a sequence with the elements `(ECMA|Java)` and `Script`. - */ -class RegExpSequence extends RegExpTerm, TRegExpSequence { - RegExpSequence() { this = TRegExpSequence(re, start, end) } - - override RegExpTerm getChild(int i) { result = seqChild(re, start, end, i) } - - /** Gets the element preceding `element` in this sequence. */ - RegExpTerm previousElement(RegExpTerm element) { element = this.nextElement(result) } - - /** Gets the element following `element` in this sequence. */ - RegExpTerm nextElement(RegExpTerm element) { - exists(int i | - element = this.getChild(i) and - result = this.getChild(i + 1) - ) - } - - override string getPrimaryQLClass() { result = "RegExpSequence" } -} - -pragma[nomagic] -private int seqChildEnd(Regex re, int start, int end, int i) { - result = seqChild(re, start, end, i).getEnd() -} - -// moved out so we can use it in the charpred -private RegExpTerm seqChild(Regex re, int start, int end, int i) { - re.sequence(start, end) and - ( - i = 0 and - exists(int itemEnd | - re.item(start, itemEnd) and - result.occursInRegex(re, start, itemEnd) - ) - or - i > 0 and - exists(int itemStart, int itemEnd | itemStart = seqChildEnd(re, start, end, i - 1) | - re.item(itemStart, itemEnd) and - result.occursInRegex(re, itemStart, itemEnd) - ) - ) -} - -/** - * An alternative term, that is, a term of the form `a|b`. - * - * Example: - * - * ``` - * ECMA|Java - * ``` - */ -class RegExpAlt extends RegExpTerm, TRegExpAlt { - RegExpAlt() { this = TRegExpAlt(re, start, end) } - - override RegExpTerm getChild(int i) { - i = 0 and - exists(int part_end | - re.alternationOption(start, end, start, part_end) and + override RegExpTerm getChild(int i) { + i = 0 and result.occursInRegex(re, start, part_end) - ) - or - i > 0 and - exists(int part_start, int part_end | - part_start = this.getChild(i - 1).getEnd() + 1 // allow for the | - | - re.alternationOption(start, end, part_start, part_end) and - result.occursInRegex(re, part_start, part_end) - ) + } + + /** Holds if this term may match zero times. */ + predicate mayBeEmpty() { maybe_empty = true } + + /** Holds if this term may match an unlimited number of times. */ + predicate mayRepeatForever() { may_repeat_forever = true } + + /** Gets the quantifier for this term. That is e.g "?" for "a?". */ + string getQuantifier() { result = re.getText().substring(part_end, end) } + + /** Holds if this is a possessive quantifier, e.g. a*+. */ + predicate isPossessive() { + exists(string q | q = this.getQuantifier() | + q.length() > 1 and q.charAt(q.length() - 1) = "+" + ) + } + + override string getPrimaryQLClass() { result = "RegExpQuantifier" } } - override string getPrimaryQLClass() { result = "RegExpAlt" } -} - -/** - * An escaped regular expression term, that is, a regular expression - * term starting with a backslash, which is not a backreference. - * - * Example: - * - * ``` - * \. - * \w - * ``` - */ -class RegExpEscape extends RegExpNormalChar { - RegExpEscape() { re.escapedCharacter(start, end) } - /** - * Gets the name of the escaped; for example, `w` for `\w`. - * TODO: Handle named escapes. + * A regular expression term that permits unlimited repetitions. */ - override string getValue() { - not this.isUnicode() and - this.isIdentityEscape() and - result = this.getUnescaped() - or - this.getUnescaped() = "n" and result = "\n" - or - this.getUnescaped() = "r" and result = "\r" - or - this.getUnescaped() = "t" and result = "\t" - or - this.getUnescaped() = "f" and result = 12.toUnicode() // form feed - or - this.getUnescaped() = "a" and result = 7.toUnicode() // alert/bell - or - this.getUnescaped() = "e" and result = 27.toUnicode() // escape (0x1B) - or - this.isUnicode() and - result = this.getUnicode() - } - - /** Holds if this terms name is given by the part following the escape character. */ - predicate isIdentityEscape() { not this.getUnescaped() in ["n", "r", "t", "f", "a", "e"] } - - override string getPrimaryQLClass() { result = "RegExpEscape" } - - /** Gets the part of the term following the escape character. That is e.g. "w" if the term is "\w". */ - private string getUnescaped() { result = this.getText().suffix(1) } - - /** - * Gets the text for this escape. That is e.g. "\w". - */ - private string getText() { result = re.getText().substring(start, end) } - - /** - * Holds if this is a unicode escape. - */ - private predicate isUnicode() { this.getText().matches(["\\u%", "\\x%"]) } - - /** - * Gets the unicode char for this escape. - * E.g. for `\u0061` this returns "a". - */ - private string getUnicode() { - exists(int codepoint | codepoint = sum(this.getHexValueFromUnicode(_)) | - result = codepoint.toUnicode() - ) - } - - /** Gets the part of this escape that is a hexidecimal string */ - private string getHexString() { - this.isUnicode() and - if this.getText().matches("\\u%") // \uhhhh - then result = this.getText().suffix(2) - else - if this.getText().matches("\\x{%") // \x{h..h} - then result = this.getText().substring(3, this.getText().length() - 1) - else result = this.getText().suffix(2) // \xhh + class InfiniteRepetitionQuantifier extends RegExpQuantifier { + InfiniteRepetitionQuantifier() { this.mayRepeatForever() } } /** - * Gets int value for the `index`th char in the hex number of the unicode escape. - * E.g. for `\u0061` and `index = 2` this returns 96 (the number `6` interpreted as hex). - */ - private int getHexValueFromUnicode(int index) { - this.isUnicode() and - exists(string hex, string char | hex = this.getHexString() | - char = hex.charAt(index) and - result = 16.pow(hex.length() - index - 1) * toHex(char) - ) - } -} - -/** - * Gets the hex number for the `hex` char. - */ -private int toHex(string hex) { - result = [0 .. 9] and hex = result.toString() - or - result = 10 and hex = ["a", "A"] - or - result = 11 and hex = ["b", "B"] - or - result = 12 and hex = ["c", "C"] - or - result = 13 and hex = ["d", "D"] - or - result = 14 and hex = ["e", "E"] - or - result = 15 and hex = ["f", "F"] -} - -/** - * A character class escape in a regular expression. - * That is, an escaped character that denotes multiple characters. - * - * Examples: - * - * ``` - * \w - * \S - * ``` - */ -class RegExpCharacterClassEscape extends RegExpEscape { - RegExpCharacterClassEscape() { - this.getValue() in ["d", "D", "s", "S", "w", "W", "h", "H", "v", "V"] or - this.getValue().charAt(0) in ["p", "P"] - } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpCharacterClassEscape" } -} - -/** - * A named character class in a regular expression. - * - * Examples: - * - * ``` - * \p{Digit} - * \p{IsLowerCase} - */ -class RegExpNamedProperty extends RegExpCharacterClassEscape { - boolean inverted; - string name; - - RegExpNamedProperty() { - name = this.getValue().substring(2, this.getValue().length() - 1) and - ( - inverted = false and - this.getValue().charAt(0) = "p" - or - inverted = true and - this.getValue().charAt(0) = "P" - ) - } - - /** Holds if this class is inverted. */ - predicate isInverted() { inverted = true } - - /** Gets the name of this class. */ - string getClassName() { result = name } - - /** - * Gets an equivalent single-chcracter escape sequence for this class (e.g. \d) if possible, excluding the escape character. - */ - string getBackslashEquivalent() { - exists(string eq | if inverted = true then result = eq.toUpperCase() else result = eq | - name = ["Digit", "IsDigit"] and - eq = "d" - or - name = ["Space", "IsWhite_Space"] and - eq = "s" - ) - } -} - -/** - * A character class in a regular expression. - * - * Examples: - * - * ``` - * [a-z_] - * [^<>&] - * ``` - */ -class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass { - RegExpCharacterClass() { this = TRegExpCharacterClass(re, start, end) } - - /** Holds if this character class is inverted, matching the opposite of its content. */ - predicate isInverted() { re.getChar(start + 1) = "^" } - - /** Holds if this character class can match anything. */ - predicate isUniversalClass() { - // [^] - this.isInverted() and not exists(this.getAChild()) - or - // [\w\W] and similar - not this.isInverted() and - exists(string cce1, string cce2 | - cce1 = this.getAChild().(RegExpCharacterClassEscape).getValue() and - cce2 = this.getAChild().(RegExpCharacterClassEscape).getValue() - | - cce1 != cce2 and cce1.toLowerCase() = cce2.toLowerCase() - ) - } - - override RegExpTerm getChild(int i) { - i = 0 and - exists(int itemStart, int itemEnd | - re.charSetStart(start, itemStart) and - re.charSetChild(start, itemStart, itemEnd) and - result.occursInRegex(re, itemStart, itemEnd) - ) - or - i > 0 and - exists(int itemStart, int itemEnd | itemStart = this.getChild(i - 1).getEnd() | - result.occursInRegex(re, itemStart, itemEnd) and - re.charSetChild(start, itemStart, itemEnd) - ) - } - - override string getPrimaryQLClass() { result = "RegExpCharacterClass" } -} - -/** - * A character range in a character class in a regular expression. - * - * Example: - * - * ``` - * a-z - * ``` - */ -class RegExpCharacterRange extends RegExpTerm, TRegExpCharacterRange { - int lower_end; - int upper_start; - - RegExpCharacterRange() { - this = TRegExpCharacterRange(re, start, end) and - re.charRange(_, start, lower_end, upper_start, end) - } - - /** Holds if this range goes from `lo` to `hi`, in effect is `lo-hi`. */ - predicate isRange(string lo, string hi) { - lo = re.getText().substring(start, lower_end) and - hi = re.getText().substring(upper_start, end) - } - - override RegExpTerm getChild(int i) { - i = 0 and - result.occursInRegex(re, start, lower_end) - or - i = 1 and - result.occursInRegex(re, upper_start, end) - } - - override string getPrimaryQLClass() { result = "RegExpCharacterRange" } -} - -/** - * A normal character in a regular expression, that is, a character - * without special meaning. This includes escaped characters. - * It also includes escape sequences that represent character classes. - * - * Examples: - * ``` - * t - * \t - * ``` - */ -class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { - RegExpNormalChar() { this = TRegExpNormalChar(re, start, end) } - - /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) - */ - predicate isCharacter() { any() } - - /** Gets the string representation of the char matched by this term. */ - string getValue() { result = re.getText().substring(start, end) } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpNormalChar" } -} - -/** - * A quoted sequence. - * - * Example: - * ``` - * \Qabc\E - * ``` - */ -class RegExpQuote extends RegExpTerm, TRegExpQuote { - string value; - - RegExpQuote() { - exists(int inner_start, int inner_end | - this = TRegExpQuote(re, start, end) and - re.quote(start, end, inner_start, inner_end) and - value = re.getText().substring(inner_start, inner_end) - ) - } - - /** Gets the string matched by this quote term. */ - string getValue() { result = value } - - override string getPrimaryQLClass() { result = "RegExpQuote" } -} - -/** - * A constant regular expression term, that is, a regular expression - * term matching a single string. This can be a single character or a quoted sequence. - * - * Example: - * - * ``` - * a - * ``` - */ -class RegExpConstant extends RegExpTerm { - string value; - - RegExpConstant() { - (value = this.(RegExpNormalChar).getValue() or value = this.(RegExpQuote).getValue()) and - not this instanceof RegExpCharacterClassEscape - } - - /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) - */ - predicate isCharacter() { any() } - - /** Gets the string matched by this constant term. */ - string getValue() { result = value } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpConstant" } -} - -/** - * A grouped regular expression. - * - * Examples: - * - * ``` - * (ECMA|Java) - * (?:ECMA|Java) - * (?['"]) - * ``` - */ -class RegExpGroup extends RegExpTerm, TRegExpGroup { - RegExpGroup() { this = TRegExpGroup(re, start, end) } - - /** - * Gets the index of this capture group within the enclosing regular - * expression literal. + * A star-quantified term. * - * For example, in the regular expression `/((a?).)(?:b)/`, the - * group `((a?).)` has index 1, the group `(a?)` nested inside it - * has index 2, and the group `(?:b)` has no index, since it is - * not a capture group. + * Example: + * + * ``` + * \w* + * ``` */ - int getNumber() { result = re.getGroupNumber(start, end) } + class RegExpStar extends InfiniteRepetitionQuantifier { + RegExpStar() { this.getQuantifier().charAt(0) = "*" } - /** Holds if this is a named capture group. */ - predicate isNamed() { exists(this.getName()) } + override string getPrimaryQLClass() { result = "RegExpStar" } + } - /** Gets the name of this capture group, if any. */ - string getName() { result = re.getGroupName(start, end) } + /** + * A plus-quantified term. + * + * Example: + * + * ``` + * \w+ + * ``` + */ + class RegExpPlus extends InfiniteRepetitionQuantifier { + RegExpPlus() { this.getQuantifier().charAt(0) = "+" } - override RegExpTerm getChild(int i) { - i = 0 and - exists(int in_start, int in_end | re.groupContents(start, end, in_start, in_end) | - result.occursInRegex(re, in_start, in_end) + override string getPrimaryQLClass() { result = "RegExpPlus" } + } + + /** + * An optional term. + * + * Example: + * + * ``` + * ;? + * ``` + */ + class RegExpOpt extends RegExpQuantifier { + RegExpOpt() { this.getQuantifier().charAt(0) = "?" } + + override string getPrimaryQLClass() { result = "RegExpOpt" } + } + + /** + * A range-quantified term + * + * Examples: + * + * ``` + * \w{2,4} + * \w{2,} + * \w{2} + * ``` + */ + class RegExpRange extends RegExpQuantifier { + string upper; + string lower; + + RegExpRange() { re.multiples(part_end, end, lower, upper) } + + /** Gets the string defining the upper bound of this range, which is empty when no such bound exists. */ + string getUpper() { result = upper } + + /** Gets the string defining the lower bound of this range, which is empty when no such bound exists. */ + string getLower() { result = lower } + + /** + * Gets the upper bound of the range, if any. + * + * If there is no upper bound, any number of repetitions is allowed. + * For a term of the form `r{lo}`, both the lower and the upper bound + * are `lo`. + */ + int getUpperBound() { result = this.getUpper().toInt() } + + /** Gets the lower bound of the range. */ + int getLowerBound() { result = this.getLower().toInt() } + + override string getPrimaryQLClass() { result = "RegExpRange" } + } + + /** + * A sequence term. + * + * Example: + * + * ``` + * (ECMA|Java)Script + * ``` + * + * This is a sequence with the elements `(ECMA|Java)` and `Script`. + */ + class RegExpSequence extends RegExpTerm, TRegExpSequence { + RegExpSequence() { this = TRegExpSequence(re, start, end) } + + override RegExpTerm getChild(int i) { result = seqChild(re, start, end, i) } + + /** Gets the element preceding `element` in this sequence. */ + RegExpTerm previousElement(RegExpTerm element) { element = this.nextElement(result) } + + /** Gets the element following `element` in this sequence. */ + RegExpTerm nextElement(RegExpTerm element) { + exists(int i | + element = this.getChild(i) and + result = this.getChild(i + 1) + ) + } + + override string getPrimaryQLClass() { result = "RegExpSequence" } + } + + pragma[nomagic] + private int seqChildEnd(Regex re, int start, int end, int i) { + result = seqChild(re, start, end, i).getEnd() + } + + // moved out so we can use it in the charpred + private RegExpTerm seqChild(Regex re, int start, int end, int i) { + re.sequence(start, end) and + ( + i = 0 and + exists(int itemEnd | + re.item(start, itemEnd) and + result.occursInRegex(re, start, itemEnd) + ) + or + i > 0 and + exists(int itemStart, int itemEnd | itemStart = seqChildEnd(re, start, end, i - 1) | + re.item(itemStart, itemEnd) and + result.occursInRegex(re, itemStart, itemEnd) + ) ) } - override string getPrimaryQLClass() { result = "RegExpGroup" } + /** + * An alternative term, that is, a term of the form `a|b`. + * + * Example: + * + * ``` + * ECMA|Java + * ``` + */ + class RegExpAlt extends RegExpTerm, TRegExpAlt { + RegExpAlt() { this = TRegExpAlt(re, start, end) } - /** Holds if this is the `n`th numbered group of literal `lit`. */ - predicate isNumberedGroupOfLiteral(RegExpLiteral lit, int n) { - lit = this.getLiteral() and n = this.getNumber() - } + override RegExpTerm getChild(int i) { + i = 0 and + exists(int part_end | + re.alternationOption(start, end, start, part_end) and + result.occursInRegex(re, start, part_end) + ) + or + i > 0 and + exists(int part_start, int part_end | + part_start = this.getChild(i - 1).getEnd() + 1 // allow for the | + | + re.alternationOption(start, end, part_start, part_end) and + result.occursInRegex(re, part_start, part_end) + ) + } - /** Holds if this is a group with name `name` of literal `lit`. */ - predicate isNamedGroupOfLiteral(RegExpLiteral lit, string name) { - lit = this.getLiteral() and name = this.getName() - } -} - -/** - * A special character in a regular expression. - * - * Examples: - * ``` - * ^ - * $ - * . - * ``` - */ -class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { - string char; - - RegExpSpecialChar() { - this = TRegExpSpecialChar(re, start, end) and - re.specialCharacter(start, end, char) + override string getPrimaryQLClass() { result = "RegExpAlt" } } /** - * Holds if this constant represents a valid Unicode character (as opposed - * to a surrogate code point that does not correspond to a character by itself.) + * An escaped regular expression term, that is, a regular expression + * term starting with a backslash, which is not a backreference. + * + * Example: + * + * ``` + * \. + * \w + * ``` */ - predicate isCharacter() { any() } + class RegExpEscape extends RegExpNormalChar { + RegExpEscape() { re.escapedCharacter(start, end) } - /** Gets the char for this term. */ - string getChar() { result = char } + /** + * Gets the name of the escaped; for example, `w` for `\w`. + * TODO: Handle named escapes. + */ + override string getValue() { + not this.isUnicode() and + this.isIdentityEscape() and + result = this.getUnescaped() + or + this.getUnescaped() = "n" and result = "\n" + or + this.getUnescaped() = "r" and result = "\r" + or + this.getUnescaped() = "t" and result = "\t" + or + this.getUnescaped() = "f" and result = 12.toUnicode() // form feed + or + this.getUnescaped() = "a" and result = 7.toUnicode() // alert/bell + or + this.getUnescaped() = "e" and result = 27.toUnicode() // escape (0x1B) + or + this.isUnicode() and + result = this.getUnicode() + } - override RegExpTerm getChild(int i) { none() } + /** Holds if this terms name is given by the part following the escape character. */ + predicate isIdentityEscape() { not this.getUnescaped() in ["n", "r", "t", "f", "a", "e"] } - override string getPrimaryQLClass() { result = "RegExpSpecialChar" } -} + override string getPrimaryQLClass() { result = "RegExpEscape" } -/** - * A dot regular expression. - * - * Example: - * - * ``` - * . - * ``` - */ -class RegExpDot extends RegExpSpecialChar { - RegExpDot() { this.getChar() = "." } + /** Gets the part of the term following the escape character. That is e.g. "w" if the term is "\w". */ + private string getUnescaped() { result = this.getText().suffix(1) } - override string getPrimaryQLClass() { result = "RegExpDot" } -} + /** + * Gets the text for this escape. That is e.g. "\w". + */ + private string getText() { result = re.getText().substring(start, end) } -/** - * A dollar assertion `$` matching the end of a line. - * - * Example: - * - * ``` - * $ - * ``` - */ -class RegExpDollar extends RegExpSpecialChar { - RegExpDollar() { this.getChar() = "$" } + /** + * Holds if this is a unicode escape. + */ + private predicate isUnicode() { this.getText().matches(["\\u%", "\\x%"]) } - override string getPrimaryQLClass() { result = "RegExpDollar" } -} + /** + * Gets the unicode char for this escape. + * E.g. for `\u0061` this returns "a". + */ + private string getUnicode() { + exists(int codepoint | codepoint = sum(this.getHexValueFromUnicode(_)) | + result = codepoint.toUnicode() + ) + } -/** - * A caret assertion `^` matching the beginning of a line. - * - * Example: - * - * ``` - * ^ - * ``` - */ -class RegExpCaret extends RegExpSpecialChar { - RegExpCaret() { this.getChar() = "^" } + /** Gets the part of this escape that is a hexidecimal string */ + private string getHexString() { + this.isUnicode() and + if this.getText().matches("\\u%") // \uhhhh + then result = this.getText().suffix(2) + else + if this.getText().matches("\\x{%") // \x{h..h} + then result = this.getText().substring(3, this.getText().length() - 1) + else result = this.getText().suffix(2) // \xhh + } - override string getPrimaryQLClass() { result = "RegExpCaret" } -} - -/** - * A zero-width match, that is, either an empty group or an assertion. - * - * Examples: - * ``` - * () - * (?=\w) - * ``` - */ -class RegExpZeroWidthMatch extends RegExpGroup { - RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) } - - override RegExpTerm getChild(int i) { none() } - - override string getPrimaryQLClass() { result = "RegExpZeroWidthMatch" } -} - -/** - * A zero-width lookahead or lookbehind assertion. - * - * Examples: - * - * ``` - * (?=\w) - * (?!\n) - * (?<=\.) - * (?` - * in a regular expression. - * - * Examples: - * - * ``` - * \1 - * (?P=quote) - * ``` - */ -class RegExpBackRef extends RegExpTerm, TRegExpBackRef { - RegExpBackRef() { this = TRegExpBackRef(re, start, end) } /** - * Gets the number of the capture group this back reference refers to, if any. + * A character escape in a regular expression. + * + * Example: + * + * ``` + * \. + * ``` */ - int getNumber() { result = re.getBackrefNumber(start, end) } + class RegExpCharEscape = RegExpEscape; /** - * Gets the name of the capture group this back reference refers to, if any. + * A word boundary, that is, a regular expression term of the form `\b`. */ - string getName() { result = re.getBackrefName(start, end) } + class RegExpWordBoundary extends RegExpSpecialChar { + RegExpWordBoundary() { this.getChar() = "\\b" } + } - /** Gets the capture group this back reference refers to. */ - RegExpGroup getGroup() { - result.isNumberedGroupOfLiteral(this.getLiteral(), this.getNumber()) + /** + * A non-word boundary, that is, a regular expression term of the form `\B`. + */ + class RegExpNonWordBoundary extends RegExpSpecialChar { + RegExpNonWordBoundary() { this.getChar() = "\\B" } + } + + /** + * Gets the hex number for the `hex` char. + */ + private int toHex(string hex) { + result = [0 .. 9] and hex = result.toString() or - result.isNamedGroupOfLiteral(this.getLiteral(), this.getName()) + result = 10 and hex = ["a", "A"] + or + result = 11 and hex = ["b", "B"] + or + result = 12 and hex = ["c", "C"] + or + result = 13 and hex = ["d", "D"] + or + result = 14 and hex = ["e", "E"] + or + result = 15 and hex = ["f", "F"] } - override RegExpTerm getChild(int i) { none() } + /** + * A character class escape in a regular expression. + * That is, an escaped character that denotes multiple characters. + * + * Examples: + * + * ``` + * \w + * \S + * ``` + */ + class RegExpCharacterClassEscape extends RegExpEscape { + RegExpCharacterClassEscape() { + this.getValue() in ["d", "D", "s", "S", "w", "W", "h", "H", "v", "V"] or + this.getValue().charAt(0) in ["p", "P"] + } - override string getPrimaryQLClass() { result = "RegExpBackRef" } + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpCharacterClassEscape" } + } + + /** + * A named character class in a regular expression. + * + * Examples: + * + * ``` + * \p{Digit} + * \p{IsLowerCase} + */ + additional class RegExpNamedProperty extends RegExpCharacterClassEscape { + boolean inverted; + string name; + + RegExpNamedProperty() { + name = this.getValue().substring(2, this.getValue().length() - 1) and + ( + inverted = false and + this.getValue().charAt(0) = "p" + or + inverted = true and + this.getValue().charAt(0) = "P" + ) + } + + /** Holds if this class is inverted. */ + predicate isInverted() { inverted = true } + + /** Gets the name of this class. */ + string getClassName() { result = name } + + /** + * Gets an equivalent single-chcracter escape sequence for this class (e.g. \d) if possible, excluding the escape character. + */ + string getBackslashEquivalent() { + exists(string eq | if inverted = true then result = eq.toUpperCase() else result = eq | + name = ["Digit", "IsDigit"] and + eq = "d" + or + name = ["Space", "IsWhite_Space"] and + eq = "s" + ) + } + } + + /** + * A character class in a regular expression. + * + * Examples: + * + * ``` + * [a-z_] + * [^<>&] + * ``` + */ + class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass { + RegExpCharacterClass() { this = TRegExpCharacterClass(re, start, end) } + + /** Holds if this character class is inverted, matching the opposite of its content. */ + predicate isInverted() { re.getChar(start + 1) = "^" } + + /** Holds if this character class can match anything. */ + predicate isUniversalClass() { + // [^] + this.isInverted() and not exists(this.getAChild()) + or + // [\w\W] and similar + not this.isInverted() and + exists(string cce1, string cce2 | + cce1 = this.getAChild().(RegExpCharacterClassEscape).getValue() and + cce2 = this.getAChild().(RegExpCharacterClassEscape).getValue() + | + cce1 != cce2 and cce1.toLowerCase() = cce2.toLowerCase() + ) + } + + override RegExpTerm getChild(int i) { + i = 0 and + exists(int itemStart, int itemEnd | + re.charSetStart(start, itemStart) and + re.charSetChild(start, itemStart, itemEnd) and + result.occursInRegex(re, itemStart, itemEnd) + ) + or + i > 0 and + exists(int itemStart, int itemEnd | itemStart = this.getChild(i - 1).getEnd() | + result.occursInRegex(re, itemStart, itemEnd) and + re.charSetChild(start, itemStart, itemEnd) + ) + } + + override string getPrimaryQLClass() { result = "RegExpCharacterClass" } + } + + /** + * A character range in a character class in a regular expression. + * + * Example: + * + * ``` + * a-z + * ``` + */ + class RegExpCharacterRange extends RegExpTerm, TRegExpCharacterRange { + int lower_end; + int upper_start; + + RegExpCharacterRange() { + this = TRegExpCharacterRange(re, start, end) and + re.charRange(_, start, lower_end, upper_start, end) + } + + /** Holds if this range goes from `lo` to `hi`, in effect is `lo-hi`. */ + predicate isRange(string lo, string hi) { + lo = re.getText().substring(start, lower_end) and + hi = re.getText().substring(upper_start, end) + } + + override RegExpTerm getChild(int i) { + i = 0 and + result.occursInRegex(re, start, lower_end) + or + i = 1 and + result.occursInRegex(re, upper_start, end) + } + + override string getPrimaryQLClass() { result = "RegExpCharacterRange" } + } + + /** + * A normal character in a regular expression, that is, a character + * without special meaning. This includes escaped characters. + * It also includes escape sequences that represent character classes. + * + * Examples: + * ``` + * t + * \t + * ``` + */ + additional class RegExpNormalChar extends RegExpTerm, TRegExpNormalChar { + RegExpNormalChar() { this = TRegExpNormalChar(re, start, end) } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the string representation of the char matched by this term. */ + string getValue() { result = re.getText().substring(start, end) } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpNormalChar" } + } + + /** + * A quoted sequence. + * + * Example: + * ``` + * \Qabc\E + * ``` + */ + additional class RegExpQuote extends RegExpTerm, TRegExpQuote { + string value; + + RegExpQuote() { + exists(int inner_start, int inner_end | + this = TRegExpQuote(re, start, end) and + re.quote(start, end, inner_start, inner_end) and + value = re.getText().substring(inner_start, inner_end) + ) + } + + /** Gets the string matched by this quote term. */ + string getValue() { result = value } + + override string getPrimaryQLClass() { result = "RegExpQuote" } + } + + /** + * A constant regular expression term, that is, a regular expression + * term matching a single string. This can be a single character or a quoted sequence. + * + * Example: + * + * ``` + * a + * ``` + */ + class RegExpConstant extends RegExpTerm { + string value; + + RegExpConstant() { + (value = this.(RegExpNormalChar).getValue() or value = this.(RegExpQuote).getValue()) and + not this instanceof RegExpCharacterClassEscape + } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the string matched by this constant term. */ + string getValue() { result = value } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpConstant" } + } + + /** + * A grouped regular expression. + * + * Examples: + * + * ``` + * (ECMA|Java) + * (?:ECMA|Java) + * (?['"]) + * ``` + */ + class RegExpGroup extends RegExpTerm, TRegExpGroup { + RegExpGroup() { this = TRegExpGroup(re, start, end) } + + /** + * Gets the index of this capture group within the enclosing regular + * expression literal. + * + * For example, in the regular expression `/((a?).)(?:b)/`, the + * group `((a?).)` has index 1, the group `(a?)` nested inside it + * has index 2, and the group `(?:b)` has no index, since it is + * not a capture group. + */ + int getNumber() { result = re.getGroupNumber(start, end) } + + /** Holds if this is a named capture group. */ + predicate isNamed() { exists(this.getName()) } + + /** Gets the name of this capture group, if any. */ + string getName() { result = re.getGroupName(start, end) } + + override RegExpTerm getChild(int i) { + i = 0 and + exists(int in_start, int in_end | re.groupContents(start, end, in_start, in_end) | + result.occursInRegex(re, in_start, in_end) + ) + } + + override string getPrimaryQLClass() { result = "RegExpGroup" } + + /** Holds if this is the `n`th numbered group of literal `lit`. */ + predicate isNumberedGroupOfLiteral(RegExpLiteral lit, int n) { + lit = this.getLiteral() and n = this.getNumber() + } + + /** Holds if this is a group with name `name` of literal `lit`. */ + predicate isNamedGroupOfLiteral(RegExpLiteral lit, string name) { + lit = this.getLiteral() and name = this.getName() + } + + /** Holds if this is a capture group. */ + predicate isCapture() { exists(this.getNumber()) } + } + + /** + * A special character in a regular expression. + * + * Examples: + * ``` + * ^ + * $ + * . + * ``` + */ + additional class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar { + string char; + + RegExpSpecialChar() { + this = TRegExpSpecialChar(re, start, end) and + re.specialCharacter(start, end, char) + } + + /** + * Holds if this constant represents a valid Unicode character (as opposed + * to a surrogate code point that does not correspond to a character by itself.) + */ + predicate isCharacter() { any() } + + /** Gets the char for this term. */ + string getChar() { result = char } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpSpecialChar" } + } + + /** + * A dot regular expression. + * + * Example: + * + * ``` + * . + * ``` + */ + class RegExpDot extends RegExpSpecialChar { + RegExpDot() { this.getChar() = "." } + + override string getPrimaryQLClass() { result = "RegExpDot" } + } + + /** + * A term that matches a specific position between characters in the string. + * + * Example: + * + * ``` + * ^ + * ``` + */ + class RegExpAnchor extends RegExpSpecialChar { + RegExpAnchor() { this.getChar() = ["$", "^"] } + + override string getPrimaryQLClass() { result = "RegExpAnchor" } + } + + /** + * A dollar assertion `$` matching the end of a line. + * + * Example: + * + * ``` + * $ + * ``` + */ + class RegExpDollar extends RegExpAnchor { + RegExpDollar() { this.getChar() = "$" } + + override string getPrimaryQLClass() { result = "RegExpDollar" } + } + + /** + * A caret assertion `^` matching the beginning of a line. + * + * Example: + * + * ``` + * ^ + * ``` + */ + class RegExpCaret extends RegExpAnchor { + RegExpCaret() { this.getChar() = "^" } + + override string getPrimaryQLClass() { result = "RegExpCaret" } + } + + /** + * A zero-width match, that is, either an empty group or an assertion. + * + * Examples: + * ``` + * () + * (?=\w) + * ``` + */ + additional class RegExpZeroWidthMatch extends RegExpGroup { + RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpZeroWidthMatch" } + } + + /** + * A zero-width lookahead or lookbehind assertion. + * + * Examples: + * + * ``` + * (?=\w) + * (?!\n) + * (?<=\.) + * (?` + * in a regular expression. + * + * Examples: + * + * ``` + * \1 + * (?P=quote) + * ``` + */ + class RegExpBackRef extends RegExpTerm, TRegExpBackRef { + RegExpBackRef() { this = TRegExpBackRef(re, start, end) } + + /** + * Gets the number of the capture group this back reference refers to, if any. + */ + int getNumber() { result = re.getBackrefNumber(start, end) } + + /** + * Gets the name of the capture group this back reference refers to, if any. + */ + string getName() { result = re.getBackrefName(start, end) } + + /** Gets the capture group this back reference refers to. */ + RegExpGroup getGroup() { + result.isNumberedGroupOfLiteral(this.getLiteral(), this.getNumber()) + or + result.isNamedGroupOfLiteral(this.getLiteral(), this.getName()) + } + + override RegExpTerm getChild(int i) { none() } + + override string getPrimaryQLClass() { result = "RegExpBackRef" } + } + + class Top = RegExpParent; + + /** + * Holds if `term` is an escape class representing e.g. `\d`. + * `clazz` is which character class it represents, e.g. "d" for `\d`. + */ + predicate isEscapeClass(RegExpTerm term, string clazz) { + term.(RegExpCharacterClassEscape).getValue() = clazz + or + term.(RegExpNamedProperty).getBackslashEquivalent() = clazz + } + + /** + * Holds if `term` is a possessive quantifier, e.g. `a*+`. + */ + predicate isPossessive(RegExpQuantifier term) { term.isPossessive() } + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against. + */ + predicate matchesAnyPrefix(RegExpTerm term) { not term.getRegex().matchesFullString() } + + /** + * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against. + */ + predicate matchesAnySuffix(RegExpTerm term) { not term.getRegex().matchesFullString() } + + /** + * Holds if the regular expression should not be considered. + * + * We make the pragmatic performance optimization to ignore regular expressions in files + * that do not belong to the project code (such as installed dependencies). + */ + predicate isExcluded(RegExpParent parent) { + not exists(parent.getRegex().getLocation().getFile().getRelativePath()) + or + // Regexes with many occurrences of ".*" may cause the polynomial ReDoS computation to explode, so + // we explicitly exclude these. + strictcount(int i | exists(parent.getRegex().getText().regexpFind("\\.\\*", i, _)) | i) > 10 + } + + /** + * Holds if `root` has the `i` flag for case-insensitive matching. + */ + predicate isIgnoreCase(RegExpTerm root) { + root.isRootTerm() and + root.getLiteral().isIgnoreCase() + } + + /** + * Gets the flags for `root`, or the empty string if `root` has no flags. + */ + additional deprecated string getFlags(RegExpTerm root) { + root.isRootTerm() and + result = root.getLiteral().getFlags() + } + + /** + * Holds if `root` has the `s` flag for multi-line matching. + */ + predicate isDotAll(RegExpTerm root) { + root.isRootTerm() and + root.getLiteral().isDotAll() + } } - -/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */ -RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegex() = re and result.isRootTerm() } diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll index 5252bbfa627..993c2941733 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll @@ -28,37 +28,6 @@ class IntentRedirectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); } -private class DefaultIntentRedirectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "android.app;Activity;true;bindService;;;Argument[0];intent-start;manual", - "android.app;Activity;true;bindServiceAsUser;;;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityAsCaller;;;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(Intent,int);;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(Intent,int,Bundle);;Argument[0];intent-start;manual", - "android.app;Activity;true;startActivityForResult;(String,Intent,int,Bundle);;Argument[1];intent-start;manual", - "android.app;Activity;true;startActivityForResultAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivities;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivity;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivityAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;startActivityFromChild;;;Argument[1];intent-start;manual", - "android.content;Context;true;startActivityFromFragment;;;Argument[1];intent-start;manual", - "android.content;Context;true;startActivityIfNeeded;;;Argument[0];intent-start;manual", - "android.content;Context;true;startForegroundService;;;Argument[0];intent-start;manual", - "android.content;Context;true;startService;;;Argument[0];intent-start;manual", - "android.content;Context;true;startServiceAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcastAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendBroadcastWithMultiplePermissions;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyBroadcastAsUser;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyOrderedBroadcast;;;Argument[0];intent-start;manual", - "android.content;Context;true;sendStickyOrderedBroadcastAsUser;;;Argument[0];intent-start;manual" - ] - } -} - /** Default sink for Intent redirection vulnerabilities. */ private class DefaultIntentRedirectionSink extends IntentRedirectionSink { DefaultIntentRedirectionSink() { sinkNode(this, "intent-start") } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 5b836e4c01f..89cc7ac021b 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -7,7 +7,6 @@ import java import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.CleartextStorageQuery -import semmle.code.java.security.Files import semmle.code.xml.AndroidManifest private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink { diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 042018d3e34..3a91ad342dd 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -290,9 +290,7 @@ string getSecureAlgorithmRegex() { * algorithm. For example, methods returning ciphers, decryption methods, * constructors of cipher classes, etc. */ -abstract class CryptoAlgoSpec extends Top { - CryptoAlgoSpec() { this instanceof Call } - +abstract class CryptoAlgoSpec extends Top instanceof Call { abstract Expr getAlgoSpec(); } diff --git a/java/ql/lib/semmle/code/java/security/ExternalProcess.qll b/java/ql/lib/semmle/code/java/security/ExternalProcess.qll index fe5e46d5efb..9a061c7a419 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalProcess.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalProcess.qll @@ -1,4 +1,5 @@ -/* Definitions related to external processes. */ +/** Definitions related to external processes. */ + import semmle.code.java.Member private module Instances { diff --git a/java/ql/lib/semmle/code/java/security/Files.qll b/java/ql/lib/semmle/code/java/security/Files.qll deleted file mode 100644 index 2cc55a1076f..00000000000 --- a/java/ql/lib/semmle/code/java/security/Files.qll +++ /dev/null @@ -1,98 +0,0 @@ -/** Provides classes and predicates to work with File objects. */ - -import java -private import semmle.code.java.dataflow.ExternalFlow - -private class CreateFileSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileOutputStream;false;FileOutputStream;;;Argument[0];create-file;manual", - "java.io;RandomAccessFile;false;RandomAccessFile;;;Argument[0];create-file;manual", - "java.io;FileWriter;false;FileWriter;;;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File,String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(File,Charset);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String,String);;Argument[0];create-file;manual", - "java.io;PrintStream;false;PrintStream;(String,Charset);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File,String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(File,Charset);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String,String);;Argument[0];create-file;manual", - "java.io;PrintWriter;false;PrintWriter;(String,Charset);;Argument[0];create-file;manual", - "java.nio.file;Files;false;copy;;;Argument[1];create-file;manual", - "java.nio.file;Files;false;createDirectories;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createDirectory;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createFile;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createLink;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createSymbolicLink;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createTempDirectory;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;createTempFile;(Path,String,String,FileAttribute[]);;Argument[0];create-file;manual", - "java.nio.file;Files;false;move;;;Argument[1];create-file;manual", - "java.nio.file;Files;false;newBufferedWriter;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;newOutputStream;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;write;;;Argument[0];create-file;manual", - "java.nio.file;Files;false;writeString;;;Argument[0];create-file;manual" - ] - } -} - -private class WriteFileSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileOutputStream;false;write;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;write;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeBytes;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeChars;;;Argument[0];write-file;manual", - "java.io;RandomAccessFile;false;writeUTF;;;Argument[0];write-file;manual", - "java.io;Writer;true;append;;;Argument[0];write-file;manual", - "java.io;Writer;true;write;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;append;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;format;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintStream;true;format;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintStream;true;print;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;printf;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintStream;true;printf;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintStream;true;println;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;write;;;Argument[0];write-file;manual", - "java.io;PrintStream;true;writeBytes;;;Argument[0];write-file;manual", - "java.io;PrintWriter;false;format;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintWriter;false;format;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintWriter;false;print;;;Argument[0];write-file;manual", - "java.io;PrintWriter;false;printf;(String,Object[]);;Argument[0..1];write-file;manual", - "java.io;PrintWriter;false;printf;(Locale,String,Object[]);;Argument[1..2];write-file;manual", - "java.io;PrintWriter;false;println;;;Argument[0];write-file;manual", - "java.nio.file;Files;false;write;;;Argument[1];write-file;manual", - "java.nio.file;Files;false;writeString;;;Argument[1];write-file;manual" - ] - } -} - -private class FileSummaryModels extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual", - "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual", - "java.io;File;true;getAbsoluteFile;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getCanonicalFile;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;getCanonicalPath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toPath;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.io;File;true;toURI;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;resolve;;;Argument[-1..0];ReturnValue;taint;manual", - "java.nio.file;Path;true;toAbsolutePath;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toUri;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual", - "java.nio.file;FileSystem;true;getPath;;;Argument[0];ReturnValue;taint;manual", - "java.nio.file;FileSystem;true;getRootDirectories;;;Argument[0];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll index 78cc2690bec..046993f6658 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll @@ -43,22 +43,6 @@ class FragmentInjectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node n1, DataFlow::Node n2); } -private class FragmentInjectionSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - ["android.app", "android.support.v4.app", "androidx.fragment.app"] + - ";FragmentTransaction;true;" + - [ - "add;(Class,Bundle,String);;Argument[0]", "add;(Fragment,String);;Argument[0]", - "add;(int,Class,Bundle);;Argument[1]", "add;(int,Fragment);;Argument[1]", - "add;(int,Class,Bundle,String);;Argument[1]", "add;(int,Fragment,String);;Argument[1]", - "attach;(Fragment);;Argument[0]", "replace;(int,Class,Bundle);;Argument[1]", - "replace;(int,Fragment);;Argument[1]", "replace;(int,Class,Bundle,String);;Argument[1]", - "replace;(int,Fragment,String);;Argument[1]", - ] + ";fragment-injection;manual" - } -} - private class DefaultFragmentInjectionSink extends FragmentInjectionSink { DefaultFragmentInjectionSink() { sinkNode(this, "fragment-injection") } } diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll index b735e28cd32..54ea8afce91 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll @@ -24,47 +24,6 @@ private class DefaultGroovyInjectionSink extends GroovyInjectionSink { DefaultGroovyInjectionSink() { sinkNode(this, "groovy") } } -private class DefaultGroovyInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // Signatures are specified to exclude sinks of the type `File` - "groovy.lang;GroovyShell;false;evaluate;(GroovyCodeSource);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(Reader);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(String,String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;evaluate;(URI);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(Reader);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(String,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;parse;(URI);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(GroovyCodeSource,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(GroovyCodeSource,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(Reader,String,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(Reader,String,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(String,String,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(String,String,List);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(URI,String[]);;Argument[0];groovy;manual", - "groovy.lang;GroovyShell;false;run;(URI,List);;Argument[0];groovy;manual", - "groovy.util;Eval;false;me;(String);;Argument[0];groovy;manual", - "groovy.util;Eval;false;me;(String,Object,String);;Argument[2];groovy;manual", - "groovy.util;Eval;false;x;(Object,String);;Argument[1];groovy;manual", - "groovy.util;Eval;false;xy;(Object,Object,String);;Argument[2];groovy;manual", - "groovy.util;Eval;false;xyz;(Object,Object,Object,String);;Argument[3];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(GroovyCodeSource);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(GroovyCodeSource,boolean);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(InputStream,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(Reader,String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(String);;Argument[0];groovy;manual", - "groovy.lang;GroovyClassLoader;false;parseClass;(String,String);;Argument[0];groovy;manual", - "org.codehaus.groovy.control;CompilationUnit;false;compile;;;Argument[-1];groovy;manual" - ] - } -} - /** A set of additional taint steps to consider when taint tracking Groovy related data flows. */ private class DefaultGroovyInjectionAdditionalTaintStep extends GroovyInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 3441cfaef18..308b8037554 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -85,42 +85,20 @@ private class MutablePendingIntentFlowStep extends ImplicitPendingIntentAddition // unless it is at least sometimes explicitly marked immutable and never marked mutable. // Note: for API level < 31, PendingIntents were mutable by default, whereas since then // they are immutable by default. - not TaintTracking::localExprTaint(any(ImmutablePendingIntentFlag flag).getAnAccess(), flagArg) + not bitwiseLocalTaintStep*(DataFlow::exprNode(any(ImmutablePendingIntentFlag flag) + .getAnAccess()), DataFlow::exprNode(flagArg)) or - TaintTracking::localExprTaint(any(MutablePendingIntentFlag flag).getAnAccess(), flagArg) + bitwiseLocalTaintStep*(DataFlow::exprNode(any(MutablePendingIntentFlag flag).getAnAccess()), + DataFlow::exprNode(flagArg)) ) } } -private class PendingIntentSentSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "androidx.slice;SliceProvider;true;onBindSlice;;;ReturnValue;pending-intent-sent;manual", - "androidx.slice;SliceProvider;true;onCreatePermissionRequest;;;ReturnValue;pending-intent-sent;manual", - "android.app;NotificationManager;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual", - "android.app;NotificationManager;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", - "android.app;NotificationManager;true;notifyAsPackage;(String,String,int,Notification);;Argument[3];pending-intent-sent;manual", - "android.app;NotificationManager;true;notifyAsUser;(String,int,Notification,UserHandle);;Argument[2];pending-intent-sent;manual", - "androidx.core.app;NotificationManagerCompat;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual", - "androidx.core.app;NotificationManagerCompat;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String,Bundle);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler);;Argument[2];pending-intent-sent;manual", - "android.app;PendingIntent;false;send;(Context,int,Intent);;Argument[2];pending-intent-sent;manual", - "android.app;Activity;true;setResult;(int,Intent);;Argument[1];pending-intent-sent;manual", - "android.app;AlarmManager;true;set;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setAlarmClock;;;Argument[1];pending-intent-sent;manual", - "android.app;AlarmManager;true;setAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setExact;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setExactAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual", - "android.app;AlarmManager;true;setInexactRepeating;;;Argument[3];pending-intent-sent;manual", - "android.app;AlarmManager;true;setRepeating;;;Argument[3];pending-intent-sent;manual", - "android.app;AlarmManager;true;setWindow;(int,long,long,PendingIntent);;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setAlarmClock;;;Argument[2..3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setExact;;;Argument[3];pending-intent-sent;manual", - "androidx.core.app;AlarmManagerCompat;true;setExactAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", - ] - } +/** + * Holds if taint can flow from `source` to `sink` in one local step, + * including bitwise operations. + */ +private predicate bitwiseLocalTaintStep(DataFlow::Node source, DataFlow::Node sink) { + TaintTracking::localTaintStep(source, sink) or + source.asExpr() = sink.asExpr().(BitwiseExpr).(BinaryExpr).getAnOperand() } diff --git a/java/ql/lib/semmle/code/java/security/InformationLeak.qll b/java/ql/lib/semmle/code/java/security/InformationLeak.qll index c3a4d0d286c..8fe7d215165 100644 --- a/java/ql/lib/semmle/code/java/security/InformationLeak.qll +++ b/java/ql/lib/semmle/code/java/security/InformationLeak.qll @@ -5,14 +5,6 @@ import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.security.XSS -/** CSV sink models representing methods not susceptible to XSS but outputing to an HTTP response body. */ -private class DefaultInformationLeakSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - "javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];information-leak;manual" - } -} - /** A sink that represent a method that outputs data to an HTTP response. */ abstract class InformationLeakSink extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll b/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll index e09bffca8e1..b156b594a70 100644 --- a/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll +++ b/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll @@ -2,6 +2,7 @@ private import semmle.code.java.security.Encryption private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.security.internal.EncryptionKeySizes /** A source for an insufficient key size. */ abstract class InsufficientKeySizeSource extends DataFlow::Node { @@ -21,39 +22,67 @@ private module Asymmetric { private module NonEllipticCurve { /** A source for an insufficient key size used in RSA, DSA, and DH algorithms. */ private class Source extends InsufficientKeySizeSource { - Source() { this.asExpr().(IntegerLiteral).getIntValue() < getMinKeySize() } + string algoName; - override predicate hasState(DataFlow::FlowState state) { state = getMinKeySize().toString() } + Source() { this.asExpr().(IntegerLiteral).getIntValue() < getMinKeySize(algoName) } + + override predicate hasState(DataFlow::FlowState state) { + state = getMinKeySize(algoName).toString() + } } /** A sink for an insufficient key size used in RSA, DSA, and DH algorithms. */ private class Sink extends InsufficientKeySizeSink { + string algoName; + Sink() { exists(KeyPairGenInit kpgInit, KeyPairGen kpg | - kpg.getAlgoName().matches(["RSA", "DSA", "DH"]) and + algoName in ["RSA", "DSA", "DH"] and + kpg.getAlgoName() = algoName and DataFlow::localExprFlow(kpg, kpgInit.getQualifier()) and this.asExpr() = kpgInit.getKeySizeArg() ) or - exists(Spec spec | this.asExpr() = spec.getKeySizeArg()) + exists(Spec spec | this.asExpr() = spec.getKeySizeArg() and algoName = spec.getAlgoName()) } - override predicate hasState(DataFlow::FlowState state) { state = getMinKeySize().toString() } + override predicate hasState(DataFlow::FlowState state) { + state = getMinKeySize(algoName).toString() + } } /** Returns the minimum recommended key size for RSA, DSA, and DH algorithms. */ - private int getMinKeySize() { result = 2048 } + private int getMinKeySize(string algoName) { + algoName = "RSA" and + result = minSecureKeySizeRsa() + or + algoName = "DSA" and + result = minSecureKeySizeDsa() + or + algoName = "DH" and + result = minSecureKeySizeDh() + } /** An instance of an RSA, DSA, or DH algorithm specification. */ private class Spec extends ClassInstanceExpr { + string algoName; + Spec() { - this.getConstructedType() instanceof RsaKeyGenParameterSpec or - this.getConstructedType() instanceof DsaGenParameterSpec or - this.getConstructedType() instanceof DhGenParameterSpec + this.getConstructedType() instanceof RsaKeyGenParameterSpec and + algoName = "RSA" + or + this.getConstructedType() instanceof DsaGenParameterSpec and + algoName = "DSA" + or + this.getConstructedType() instanceof DhGenParameterSpec and + algoName = "DH" } /** Gets the `keysize` argument of this instance. */ Argument getKeySizeArg() { result = this.getArgument(0) } + + /** Gets the algorithm name of this spec. */ + string getAlgoName() { result = algoName } } } @@ -87,7 +116,7 @@ private module Asymmetric { } /** Returns the minimum recommended key size for elliptic curve (EC) algorithms. */ - private int getMinKeySize() { result = 256 } + private int getMinKeySize() { result = minSecureKeySizeEcc() } /** Returns the key size from an EC algorithm's curve name string */ bindingset[algorithm] @@ -168,7 +197,7 @@ private module Symmetric { } /** Returns the minimum recommended key size for AES algorithms. */ - private int getMinKeySize() { result = 128 } + private int getMinKeySize() { result = minSecureKeySizeAes() } /** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */ private class KeyGenInit extends MethodAccess { diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll deleted file mode 100644 index ed722c2f18a..00000000000 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionSinkModels.qll +++ /dev/null @@ -1,43 +0,0 @@ -/** Provides sink models relating to Expression Language (JEXL) injection vulnerabilities. */ - -private import semmle.code.java.dataflow.ExternalFlow - -private class DefaultJexlInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // JEXL2 - "org.apache.commons.jexl2;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;setProperty;(JexlContext,Object,String,Object);;Argument[2];jexl;manual", - "org.apache.commons.jexl2;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl;manual", - "org.apache.commons.jexl2;Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Expression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlExpression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlExpression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Script;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl;manual", - // JEXL3 - "org.apache.commons.jexl3;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;setProperty;(JexlContext,Object,String);;Argument[2];jexl;manual", - "org.apache.commons.jexl3;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl;manual", - "org.apache.commons.jexl3;Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Expression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlExpression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlExpression;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Script;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;Script;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlScript;false;execute;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl;manual", - "org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index 9dca731af80..cacf725cc99 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -72,62 +72,6 @@ private class ProviderUrlJndiInjectionSink extends JndiInjectionSink, DataFlow:: } } -/** CSV sink models representing methods susceptible to JNDI injection attacks. */ -private class DefaultJndiInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.naming;Context;true;lookup;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;lookupLink;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;rename;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;list;;;Argument[0];jndi-injection;manual", - "javax.naming;Context;true;listBindings;;;Argument[0];jndi-injection;manual", - "javax.naming;InitialContext;true;doLookup;;;Argument[0];jndi-injection;manual", - "javax.management.remote;JMXConnector;true;connect;;;Argument[-1];jndi-injection;manual", - "javax.management.remote;JMXConnectorFactory;false;connect;;;Argument[0];jndi-injection;manual", - // Spring - "org.springframework.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection;manual", - // spring-ldap 1.2.x and newer - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(Name,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookup;(String,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;findByDn;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;rename;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;list;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;listBindings;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap.core;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - // spring-ldap 1.1.x - "org.springframework.ldap;LdapOperations;true;lookup;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;findByDn;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;rename;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;list;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;listBindings;;;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection;manual", - "org.springframework.ldap;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection;manual", - // Shiro - "org.apache.shiro.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection;manual" - ] - } -} - /** A set of additional taint steps to consider when taint tracking JNDI injection related data flows. */ private class DefaultJndiInjectionAdditionalTaintStep extends JndiInjectionAdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/lib/semmle/code/java/security/LdapInjection.qll b/java/ql/lib/semmle/code/java/security/LdapInjection.qll index 35c59279f4e..d78bd2f7ae1 100644 --- a/java/ql/lib/semmle/code/java/security/LdapInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LdapInjection.qll @@ -32,53 +32,6 @@ private class DefaultLdapInjectionSink extends LdapInjectionSink { DefaultLdapInjectionSink() { sinkNode(this, "ldap") } } -private class DefaultLdapInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // jndi - "javax.naming.directory;DirContext;true;search;;;Argument[0..1];ldap;manual", - // apache - "org.apache.directory.ldap.client.api;LdapConnection;true;search;;;Argument[0..2];ldap;manual", - // UnboundID: search - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(ReadOnlySearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[]);;Argument[0..7];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[]);;Argument[0..7];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,Filter,String[]);;Argument[0..3];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(SearchResultListener,String,SearchScope,String,String[]);;Argument[0..3];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[]);;Argument[0..6];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[]);;Argument[0..6];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,Filter,String[]);;Argument[0..2];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;search;(String,SearchScope,String,String[]);;Argument[0..2];ldap;manual", - // UnboundID: searchForEntry - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(ReadOnlySearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(SearchRequest);;Argument[0];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[]);;Argument[0..5];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,DereferencePolicy,int,boolean,String,String[]);;Argument[0..5];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,Filter,String[]);;Argument[0..2];ldap;manual", - "com.unboundid.ldap.sdk;LDAPConnection;false;searchForEntry;(String,SearchScope,String,String[]);;Argument[0..2];ldap;manual", - // UnboundID: asyncSearch - "com.unboundid.ldap.sdk;LDAPConnection;false;asyncSearch;;;Argument[0];ldap;manual", - // Spring - "org.springframework.ldap.core;LdapTemplate;false;find;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;findOne;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;search;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;searchForContext;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;searchForObject;;;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(LdapQuery,String);;Argument[0];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticatedLdapEntryContextCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(Name,String,String,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticatedLdapEntryContextCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback);;Argument[0..1];ldap;manual", - "org.springframework.ldap.core;LdapTemplate;false;authenticate;(String,String,String,AuthenticationErrorCallback);;Argument[0..1];ldap;manual" - ] - } -} - /** A sanitizer that clears the taint on (boxed) primitive types. */ private class DefaultLdapSanitizer extends LdapInjectionSanitizer { DefaultLdapSanitizer() { diff --git a/java/ql/lib/semmle/code/java/security/MvelInjection.qll b/java/ql/lib/semmle/code/java/security/MvelInjection.qll index 167b21edae6..a0ada3d91a1 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjection.qll @@ -28,31 +28,6 @@ private class DefaultMvelEvaluationSink extends MvelEvaluationSink { DefaultMvelEvaluationSink() { sinkNode(this, "mvel") } } -private class DefaulMvelEvaluationSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.script;CompiledScript;false;eval;;;Argument[-1];mvel;manual", - "org.mvel2;MVEL;false;eval;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;evalToBoolean;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;evalToString;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeAllExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVEL;false;executeSetExpression;;;Argument[0];mvel;manual", - "org.mvel2;MVELRuntime;false;execute;;;Argument[1];mvel;manual", - "org.mvel2.templates;TemplateRuntime;false;eval;;;Argument[0];mvel;manual", - "org.mvel2.templates;TemplateRuntime;false;execute;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelScriptEngine;false;eval;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelScriptEngine;false;evaluate;;;Argument[0];mvel;manual", - "org.mvel2.jsr223;MvelCompiledScript;false;eval;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;ExecutableStatement;false;getValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;CompiledExpression;false;getDirectValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;CompiledAccExpression;false;getValue;;;Argument[-1];mvel;manual", - "org.mvel2.compiler;Accessor;false;getValue;;;Argument[-1];mvel;manual" - ] - } -} - /** A default sanitizer that considers numeric and boolean typed data safe for building MVEL expressions */ private class DefaultMvelInjectionSanitizer extends MvelInjectionSanitizer { DefaultMvelInjectionSanitizer() { diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll index 1ebede55b78..aa10de4d3c1 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjection.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjection.qll @@ -25,29 +25,6 @@ class OgnlInjectionAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); } -private class DefaultOgnlInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.commons.ognl;Ognl;false;getValue;;;Argument[0];ognl-injection;manual", - "org.apache.commons.ognl;Ognl;false;setValue;;;Argument[0];ognl-injection;manual", - "org.apache.commons.ognl;Node;true;getValue;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl;Node;true;setValue;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl.enhance;ExpressionAccessor;true;get;;;Argument[-1];ognl-injection;manual", - "org.apache.commons.ognl.enhance;ExpressionAccessor;true;set;;;Argument[-1];ognl-injection;manual", - "ognl;Ognl;false;getValue;;;Argument[0];ognl-injection;manual", - "ognl;Ognl;false;setValue;;;Argument[0];ognl-injection;manual", - "ognl;Node;false;getValue;;;Argument[-1];ognl-injection;manual", - "ognl;Node;false;setValue;;;Argument[-1];ognl-injection;manual", - "ognl.enhance;ExpressionAccessor;true;get;;;Argument[-1];ognl-injection;manual", - "ognl.enhance;ExpressionAccessor;true;set;;;Argument[-1];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;getValue;;;Argument[0];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;setValue;;;Argument[0];ognl-injection;manual", - "com.opensymphony.xwork2.ognl;OgnlUtil;false;callMethod;;;Argument[0];ognl-injection;manual" - ] - } -} - private class DefaultOgnlInjectionSink extends OgnlInjectionSink { DefaultOgnlInjectionSink() { sinkNode(this, "ognl-injection") } } diff --git a/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll b/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll index 65e662f0bc5..06b538d4a63 100644 --- a/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll @@ -2,288 +2,7 @@ * Classes and predicates for working with suspicious character ranges. */ -// We don't need the NFA utils, just the regexp tree. -// but the below is a nice shared library that exposes the API we need. -import regexp.NfaUtils - -/** - * Gets a rank for `range` that is unique for ranges in the same file. - * Prioritizes ranges that match more characters. - */ -int rankRange(RegExpCharacterRange range) { - range = - rank[result](RegExpCharacterRange r, Location l, int low, int high | - r.getLocation() = l and - isRange(r, low, high) - | - r order by (high - low) desc, l.getStartLine(), l.getStartColumn() - ) -} - -/** Holds if `range` spans from the unicode code points `low` to `high` (both inclusive). */ -predicate isRange(RegExpCharacterRange range, int low, int high) { - exists(string lowc, string highc | - range.isRange(lowc, highc) and - low.toUnicode() = lowc and - high.toUnicode() = highc - ) -} - -/** Holds if `char` is an alpha-numeric character. */ -predicate isAlphanumeric(string char) { - // written like this to avoid having a bindingset for the predicate - char = [[48 .. 57], [65 .. 90], [97 .. 122]].toUnicode() // 0-9, A-Z, a-z -} - -/** - * Holds if the given ranges are from the same character class - * and there exists at least one character matched by both ranges. - */ -predicate overlap(RegExpCharacterRange a, RegExpCharacterRange b) { - exists(RegExpCharacterClass clz | - a = clz.getAChild() and - b = clz.getAChild() and - a != b - | - exists(int alow, int ahigh, int blow, int bhigh | - isRange(a, alow, ahigh) and - isRange(b, blow, bhigh) and - alow <= bhigh and - blow <= ahigh - ) - ) -} - -/** - * Holds if `range` overlaps with the char class `escape` from the same character class. - */ -predicate overlapsWithCharEscape(RegExpCharacterRange range, RegExpCharacterClassEscape escape) { - exists(RegExpCharacterClass clz, string low, string high | - range = clz.getAChild() and - escape = clz.getAChild() and - range.isRange(low, high) - | - escape.getValue() = "w" and - getInRange(low, high).regexpMatch("\\w") - or - escape.getValue() = "d" and - getInRange(low, high).regexpMatch("\\d") - or - escape.getValue() = "s" and - getInRange(low, high).regexpMatch("\\s") - ) -} - -/** Gets the unicode code point for a `char`. */ -bindingset[char] -int toCodePoint(string char) { result.toUnicode() = char } - -/** A character range that appears to be overly wide. */ -class OverlyWideRange extends RegExpCharacterRange { - OverlyWideRange() { - exists(int low, int high, int numChars | - isRange(this, low, high) and - numChars = (1 + high - low) and - this.getRootTerm().isUsedAsRegExp() and - numChars >= 10 - | - // across the Z-a range (which includes backticks) - toCodePoint("Z") >= low and - toCodePoint("a") <= high - or - // across the 9-A range (which includes e.g. ; and ?) - toCodePoint("9") >= low and - toCodePoint("A") <= high - or - // a non-alphanumeric char as part of the range boundaries - exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode())) and - // while still being ascii - low < 128 and - high < 128 - ) and - // allowlist for known ranges - not this = allowedWideRanges() - } - - /** Gets a string representation of a character class that matches the same chars as this range. */ - string printEquivalent() { result = RangePrinter::printEquivalentCharClass(this) } -} - -/** Gets a range that should not be reported as an overly wide range. */ -RegExpCharacterRange allowedWideRanges() { - // ~ is the last printable ASCII character, it's used right in various wide ranges. - result.isRange(_, "~") - or - // the same with " " and "!". " " is the first printable character, and "!" is the first non-white-space printable character. - result.isRange([" ", "!"], _) - or - // the `[@-_]` range is intentional - result.isRange("@", "_") - or - // starting from the zero byte is a good indication that it's purposely matching a large range. - result.isRange(0.toUnicode(), _) -} - -/** Gets a char between (and including) `low` and `high`. */ -bindingset[low, high] -private string getInRange(string low, string high) { - result = [toCodePoint(low) .. toCodePoint(high)].toUnicode() -} - -/** A module computing an equivalent character class for an overly wide range. */ -module RangePrinter { - bindingset[char] - bindingset[result] - private string next(string char) { - exists(int prev, int next | - prev.toUnicode() = char and - next.toUnicode() = result and - next = prev + 1 - ) - } - - /** Gets the points where the parts of the pretty printed range should be cut off. */ - private string cutoffs() { result = ["A", "Z", "a", "z", "0", "9"] } - - /** Gets the char to use in the low end of a range for a given `cut` */ - private string lowCut(string cut) { - cut = ["A", "a", "0"] and - result = cut - or - cut = ["Z", "z", "9"] and - result = next(cut) - } - - /** Gets the char to use in the high end of a range for a given `cut` */ - private string highCut(string cut) { - cut = ["Z", "z", "9"] and - result = cut - or - cut = ["A", "a", "0"] and - next(result) = cut - } - - /** Gets the cutoff char used for a given `part` of a range when pretty-printing it. */ - private string cutoff(OverlyWideRange range, int part) { - exists(int low, int high | isRange(range, low, high) | - result = - rank[part + 1](string cut | - cut = cutoffs() and low < toCodePoint(cut) and toCodePoint(cut) < high - | - cut order by toCodePoint(cut) - ) - ) - } - - /** Gets the number of parts we should print for a given `range`. */ - private int parts(OverlyWideRange range) { result = 1 + count(cutoff(range, _)) } - - /** Holds if the given part of a range should span from `low` to `high`. */ - private predicate part(OverlyWideRange range, int part, string low, string high) { - // first part. - part = 0 and - ( - range.isRange(low, high) and - parts(range) = 1 - or - parts(range) >= 2 and - range.isRange(low, _) and - high = highCut(cutoff(range, part)) - ) - or - // middle - part >= 1 and - part < parts(range) - 1 and - low = lowCut(cutoff(range, part - 1)) and - high = highCut(cutoff(range, part)) - or - // last. - part = parts(range) - 1 and - low = lowCut(cutoff(range, part - 1)) and - range.isRange(_, high) - } - - /** Gets an escaped `char` for use in a character class. */ - bindingset[char] - private string escape(string char) { - exists(string reg | reg = "(\\[|\\]|\\\\|-|/)" | - if char.regexpMatch(reg) then result = "\\" + char else result = char - ) - } - - /** Gets a part of the equivalent range. */ - private string printEquivalentCharClass(OverlyWideRange range, int part) { - exists(string low, string high | part(range, part, low, high) | - if - isAlphanumeric(low) and - isAlphanumeric(high) - then result = low + "-" + high - else - result = - strictconcat(string char | char = getInRange(low, high) | escape(char) order by char) - ) - } - - /** Gets the entire pretty printed equivalent range. */ - string printEquivalentCharClass(OverlyWideRange range) { - result = - strictconcat(string r, int part | - r = "[" and part = -1 and exists(range) - or - r = printEquivalentCharClass(range, part) - or - r = "]" and part = parts(range) - | - r order by part - ) - } -} - -/** Gets a char range that is overly large because of `reason`. */ -RegExpCharacterRange getABadRange(string reason, int priority) { - result instanceof OverlyWideRange and - priority = 0 and - exists(string equiv | equiv = result.(OverlyWideRange).printEquivalent() | - if equiv.length() <= 50 - then reason = "is equivalent to " + equiv - else reason = "is equivalent to " + equiv.substring(0, 50) + "..." - ) - or - priority = 1 and - exists(RegExpCharacterRange other | - reason = "overlaps with " + other + " in the same character class" and - rankRange(result) < rankRange(other) and - overlap(result, other) - ) - or - priority = 2 and - exists(RegExpCharacterClassEscape escape | - reason = "overlaps with " + escape + " in the same character class" and - overlapsWithCharEscape(result, escape) - ) - or - reason = "is empty" and - priority = 3 and - exists(int low, int high | - isRange(result, low, high) and - low > high - ) -} - -/** Holds if `range` matches suspiciously many characters. */ -predicate problem(RegExpCharacterRange range, string reason) { - reason = - strictconcat(string m, int priority | - range = getABadRange(m, priority) - | - m, ", and " order by priority desc - ) and - // specifying a range using an escape is usually OK. - not range.getAChild() instanceof RegExpEscape and - // Unicode escapes in strings are interpreted before it turns into a regexp, - // so e.g. [\u0001-\uFFFF] will just turn up as a range between two constants. - // We therefore exclude these ranges. - range.getRootTerm().getParent() instanceof RegExpLiteral and - // is used as regexp (mostly for JS where regular expressions are parsed eagerly) - range.getRootTerm().isUsedAsRegExp() -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// OverlyLargeRangeQuery should be used directly from the shared pack, and not from this file. +deprecated import codeql.regex.OverlyLargeRangeQuery::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll b/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll index 70416546b96..a43f90ae10d 100644 --- a/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll +++ b/java/ql/lib/semmle/code/java/security/PartialPathTraversalQuery.qll @@ -3,7 +3,6 @@ import java import semmle.code.java.security.PartialPathTraversal import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index bd15b0581b7..14445971b47 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -2,9 +2,10 @@ import java private import semmle.code.java.controlflow.Guards -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.SSA +private import semmle.code.java.frameworks.kotlin.IO +private import semmle.code.java.frameworks.kotlin.Text /** A sanitizer that protects against path injection vulnerabilities. */ abstract class PathInjectionSanitizer extends DataFlow::Node { } @@ -51,12 +52,14 @@ private predicate exactPathMatchGuard(Guard g, Expr e, boolean branch) { t instanceof TypeUri or t instanceof TypePath or t instanceof TypeFile or - t.hasQualifiedName("android.net", "Uri") + t.hasQualifiedName("android.net", "Uri") or + t instanceof StringsKt or + t instanceof FilesKt | + e = getVisualQualifier(ma).getUnderlyingExpr() and ma.getMethod().getDeclaringType() = t and ma = g and - ma.getMethod().getName() = ["equals", "equalsIgnoreCase"] and - e = ma.getQualifier() and + getSourceMethod(ma.getMethod()).hasName(["equals", "equalsIgnoreCase"]) and branch = true ) } @@ -87,7 +90,7 @@ private class AllowedPrefixGuard extends PathGuard instanceof MethodAccess { not isDisallowedWord(super.getAnArgument()) } - override Expr getCheckedExpr() { result = super.getQualifier() } + override Expr getCheckedExpr() { result = getVisualQualifier(this).getUnderlyingExpr() } } /** @@ -154,7 +157,7 @@ private class BlockListGuard extends PathGuard instanceof MethodAccess { isDisallowedWord(super.getAnArgument()) } - override Expr getCheckedExpr() { result = super.getQualifier() } + override Expr getCheckedExpr() { result = getVisualQualifier(this).getUnderlyingExpr() } } /** @@ -188,15 +191,31 @@ private class BlockListSanitizer extends PathInjectionSanitizer { } } +private class ConstantOrRegex extends Expr { + ConstantOrRegex() { + this instanceof CompileTimeConstantExpr or + this instanceof KtToRegex + } + + string getStringValue() { + result = this.(CompileTimeConstantExpr).getStringValue() or + result = this.(KtToRegex).getExpressionString() + } +} + private predicate isStringPrefixMatch(MethodAccess ma) { - exists(Method m | m = ma.getMethod() and m.getDeclaringType() instanceof TypeString | - m.hasName("startsWith") + exists(Method m, RefType t | + m.getDeclaringType() = t and + (t instanceof TypeString or t instanceof StringsKt) and + m = ma.getMethod() + | + getSourceMethod(m).hasName("startsWith") or - m.hasName("regionMatches") and - ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() = 0 + getSourceMethod(m).hasName("regionMatches") and + getVisualArgument(ma, 0).(CompileTimeConstantExpr).getIntValue() = 0 or m.hasName("matches") and - not ma.getArgument(0).(CompileTimeConstantExpr).getStringValue().matches(".*%") + not getVisualArgument(ma, 0).(ConstantOrRegex).getStringValue().matches(".*%") ) } @@ -206,52 +225,52 @@ private predicate isStringPrefixMatch(MethodAccess ma) { private predicate isStringPartialMatch(MethodAccess ma) { isStringPrefixMatch(ma) or - ma.getMethod().getDeclaringType() instanceof TypeString and - ma.getMethod().hasName(["contains", "matches", "regionMatches", "indexOf", "lastIndexOf"]) + exists(RefType t | t = ma.getMethod().getDeclaringType() | + t instanceof TypeString or t instanceof StringsKt + ) and + getSourceMethod(ma.getMethod()) + .hasName(["contains", "matches", "regionMatches", "indexOf", "lastIndexOf"]) } /** * Holds if `ma` is a call to a method that checks whether a path starts with a prefix. */ private predicate isPathPrefixMatch(MethodAccess ma) { - exists(RefType t | - t instanceof TypePath - or - t.hasQualifiedName("kotlin.io", "FilesKt") - | - t = ma.getMethod().getDeclaringType() and - ma.getMethod().hasName("startsWith") - ) + exists(RefType t | t = ma.getMethod().getDeclaringType() | + t instanceof TypePath or t instanceof FilesKt + ) and + getSourceMethod(ma.getMethod()).hasName("startsWith") } -private predicate isDisallowedWord(CompileTimeConstantExpr word) { +private predicate isDisallowedWord(ConstantOrRegex word) { word.getStringValue().matches(["/", "\\", "%WEB-INF%", "%/data%"]) } /** A complementary guard that protects against path traversal, by looking for the literal `..`. */ private class PathTraversalGuard extends PathGuard { + Expr checkedExpr; + PathTraversalGuard() { - exists(MethodAccess ma | - ma.getMethod().getDeclaringType() instanceof TypeString and + exists(MethodAccess ma, Method m, RefType t | + m = ma.getMethod() and + t = m.getDeclaringType() and + (t instanceof TypeString or t instanceof StringsKt) and + checkedExpr = getVisualQualifier(ma).getUnderlyingExpr() and ma.getAnArgument().(CompileTimeConstantExpr).getStringValue() = ".." | this = ma and - ma.getMethod().hasName("contains") + getSourceMethod(m).hasName("contains") or exists(EqualityTest eq | this = eq and - ma.getMethod().hasName(["indexOf", "lastIndexOf"]) and + getSourceMethod(m).hasName(["indexOf", "lastIndexOf"]) and eq.getAnOperand() = ma and eq.getAnOperand().(CompileTimeConstantExpr).getIntValue() = -1 ) ) } - override Expr getCheckedExpr() { - exists(MethodAccess ma | ma = this.(EqualityTest).getAnOperand() or ma = this | - result = ma.getQualifier() - ) - } + override Expr getCheckedExpr() { result = checkedExpr } boolean getBranch() { this instanceof MethodAccess and result = false @@ -263,15 +282,50 @@ private class PathTraversalGuard extends PathGuard { /** A complementary sanitizer that protects against path traversal using path normalization. */ private class PathNormalizeSanitizer extends MethodAccess { PathNormalizeSanitizer() { - exists(RefType t | - t instanceof TypePath or - t.hasQualifiedName("kotlin.io", "FilesKt") - | - this.getMethod().getDeclaringType() = t and + exists(RefType t | this.getMethod().getDeclaringType() = t | + (t instanceof TypePath or t instanceof FilesKt) and this.getMethod().hasName("normalize") + or + t instanceof TypeFile and + this.getMethod().hasName(["getCanonicalPath", "getCanonicalFile"]) ) - or - this.getMethod().getDeclaringType() instanceof TypeFile and - this.getMethod().hasName(["getCanonicalPath", "getCanonicalFile"]) } } + +/** + * Gets the qualifier of `ma` as seen in the source code. + * This is a helper predicate to solve discrepancies between + * what `getQualifier` actually gets in Java and Kotlin. + */ +private Expr getVisualQualifier(MethodAccess ma) { + if ma.getMethod() instanceof ExtensionMethod + then + result = ma.getArgument(ma.getMethod().(ExtensionMethod).getExtensionReceiverParameterIndex()) + else result = ma.getQualifier() +} + +/** + * Gets the argument of `ma` at position `argPos` as seen in the source code. + * This is a helper predicate to solve discrepancies between + * what `getArgument` actually gets in Java and Kotlin. + */ +bindingset[argPos] +private Argument getVisualArgument(MethodAccess ma, int argPos) { + if ma.getMethod() instanceof ExtensionMethod + then + result = + ma.getArgument(argPos + ma.getMethod().(ExtensionMethod).getExtensionReceiverParameterIndex() + + 1) + else result = ma.getArgument(argPos) +} + +/** + * Gets the proxied method if `m` is a Kotlin proxy that supplies default parameter values. + * Otherwise, just gets `m`. + */ +private Method getSourceMethod(Method m) { + m = result.getKotlinParameterDefaultsProxy() + or + not exists(Method src | m = src.getKotlinParameterDefaultsProxy()) and + result = m +} diff --git a/java/ql/lib/semmle/code/java/security/RelativePaths.qll b/java/ql/lib/semmle/code/java/security/RelativePaths.qll index 45473997489..458bb7aea5d 100644 --- a/java/ql/lib/semmle/code/java/security/RelativePaths.qll +++ b/java/ql/lib/semmle/code/java/security/RelativePaths.qll @@ -1,4 +1,5 @@ -/* Detection of strings and arrays of strings containing relative paths. */ +/** Detection of strings and arrays of strings containing relative paths. */ + import java /** diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll index d59e6c877c3..916b6df4372 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll @@ -14,22 +14,8 @@ private class DefaultHeaderSplittingSink extends HeaderSplittingSink { DefaultHeaderSplittingSink() { sinkNode(this, "header-splitting") } } -private class HeaderSplittingSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.servlet.http;HttpServletResponse;false;addCookie;;;Argument[0];header-splitting;manual", - "javax.servlet.http;HttpServletResponse;false;addHeader;;;Argument[0..1];header-splitting;manual", - "javax.servlet.http;HttpServletResponse;false;setHeader;;;Argument[0..1];header-splitting;manual", - "javax.ws.rs.core;ResponseBuilder;false;header;;;Argument[1];header-splitting;manual" - ] - } -} - /** A source that introduces data considered safe to use by a header splitting source. */ -abstract class SafeHeaderSplittingSource extends DataFlow::Node { - SafeHeaderSplittingSource() { this instanceof RemoteFlowSource } -} +abstract class SafeHeaderSplittingSource extends DataFlow::Node instanceof RemoteFlowSource { } /** A default source that introduces data considered safe to use by a header splitting source. */ private class DefaultSafeHeaderSplittingSource extends SafeHeaderSplittingSource { diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll new file mode 100644 index 00000000000..e7b5112a44a --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -0,0 +1,138 @@ +/** Definitions for the keyboard cache query */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.security.SensitiveActions +import semmle.code.xml.AndroidManifest + +/** An Android Layout XML file. */ +private class AndroidLayoutXmlFile extends XmlFile { + AndroidLayoutXmlFile() { this.getRelativePath().matches("%/res/layout/%.xml") } +} + +/** A component declared in an Android layout file. */ +class AndroidLayoutXmlElement extends XmlElement { + AndroidXmlAttribute id; + + AndroidLayoutXmlElement() { + this.getFile() instanceof AndroidLayoutXmlFile and + id = this.getAttribute("id") + } + + /** Gets the ID of this component. */ + string getId() { result = id.getValue() } + + /** Gets the class of this component. */ + Class getClass() { + this.getName() = "view" and + this.getAttribute("class").getValue() = result.getQualifiedName() + or + this.getName() = result.getQualifiedName() + or + result.hasQualifiedName(["android.widget", "android.view"], this.getName()) + } +} + +/** An XML element that represents an editable text field. */ +class AndroidEditableXmlElement extends AndroidLayoutXmlElement { + AndroidEditableXmlElement() { + this.getClass().getASourceSupertype*().hasQualifiedName("android.widget", "EditText") + } + + /** Gets the input type of this field, if any. */ + string getInputType() { result = this.getAttribute("inputType").(AndroidXmlAttribute).getValue() } +} + +/** A `findViewById` or `requireViewById` method on `Activity` or `View`. */ +private class FindViewMethod extends Method { + FindViewMethod() { + this.hasQualifiedName("android.view", "View", ["findViewById", "requireViewById"]) + or + exists(Method m | + m.hasQualifiedName("android.app", "Activity", ["findViewById", "requireViewById"]) and + this = m.getAnOverride*() + ) + } +} + +/** Gets a use of the view that has the given id. */ +private MethodAccess getAUseOfViewWithId(string id) { + exists(string name, NestedClass r_id, Field id_field | + id = "@+id/" + name and + result.getMethod() instanceof FindViewMethod and + r_id.getEnclosingType().hasName("R") and + r_id.hasName("id") and + id_field.getDeclaringType() = r_id and + id_field.hasName(name) + | + DataFlow::localExprFlow(id_field.getAnAccess(), result.getArgument(0)) + ) +} + +/** Gets the argument of a use of `setInputType` called on the view with the given id. */ +private Argument setInputTypeForId(string id) { + exists(MethodAccess setInputType | + setInputType.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") and + DataFlow::localExprFlow(getAUseOfViewWithId(id), setInputType.getQualifier()) and + result = setInputType.getArgument(0) + ) +} + +/** Holds if the given field is a constant flag indicating that an input with this type will not be cached. */ +private predicate inputTypeFieldNotCached(Field f) { + f.getDeclaringType().hasQualifiedName("android.text", "InputType") and + ( + not f.getName().matches("%TEXT%") + or + f.getName().matches("%PASSWORD%") + or + f.hasName("TYPE_TEXT_FLAG_NO_SUGGESTIONS") + ) +} + +/** Configuration that finds uses of `setInputType` for non cached fields. */ +private class GoodInputTypeConf extends DataFlow::Configuration { + GoodInputTypeConf() { this = "GoodInputTypeConf" } + + override predicate isSource(DataFlow::Node node) { + inputTypeFieldNotCached(node.asExpr().(FieldAccess).getField()) + } + + override predicate isSink(DataFlow::Node node) { node.asExpr() = setInputTypeForId(_) } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(OrBitwiseExpr bitOr | + node1.asExpr() = bitOr.getAChildExpr() and + node2.asExpr() = bitOr + ) + } +} + +/** Gets a regex indicating that an input field may contain sensitive data. */ +private string getInputSensitiveInfoRegex() { + result = + [ + getCommonSensitiveInfoRegex(), + "(?i).*(bank|credit|debit|(pass(wd|word|code|phrase))|security).*" + ] +} + +/** Holds if input using the given input type (as written in XML) is not stored in the keyboard cache. */ +bindingset[ty] +private predicate inputTypeNotCached(string ty) { + not ty.matches("%text%") + or + ty.regexpMatch("(?i).*(nosuggestions|password).*") +} + +/** Gets an input field whose contents may be sensitive and may be stored in the keyboard cache. */ +AndroidEditableXmlElement getASensitiveCachedInput() { + result.getId().regexpMatch(getInputSensitiveInfoRegex()) and + ( + not inputTypeNotCached(result.getInputType()) and + not exists(GoodInputTypeConf conf, DataFlow::Node src, DataFlow::Node sink | + conf.hasFlow(src, sink) and + sink.asExpr() = setInputTypeForId(result.getId()) + ) + ) +} diff --git a/java/ql/lib/semmle/code/java/security/SpelInjection.qll b/java/ql/lib/semmle/code/java/security/SpelInjection.qll index 76fb6191911..55f526d72f4 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjection.qll @@ -2,7 +2,6 @@ import java private import semmle.code.java.dataflow.DataFlow -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.frameworks.spring.SpringExpression /** A data flow sink for unvalidated user input that is used to construct SpEL expressions. */ diff --git a/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll b/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll index d76c77c499c..3f5810e141b 100644 --- a/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll +++ b/java/ql/lib/semmle/code/java/security/SqlUnescapedLib.qll @@ -1,4 +1,5 @@ -/* Definitions used by `SqlUnescaped.ql`. */ +/** Definitions used by `SqlUnescaped.ql`. */ + import semmle.code.java.security.ControlledString import semmle.code.java.dataflow.TaintTracking diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll index 079ef551bb3..ce2bd9d217d 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll @@ -76,33 +76,3 @@ private class DefaultTemplateInjectionSanitizer extends TemplateInjectionSanitiz this.getType() instanceof NumericType } } - -private class TemplateInjectionSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "freemarker.template;Template;true;Template;(String,Reader);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,Reader,Configuration);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,Reader,Configuration,String);;Argument[1];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration,String);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Reader,Configuration,ParserConfiguration,String);;Argument[2];ssti;manual", - "freemarker.template;Template;true;Template;(String,String,Configuration);;Argument[1];ssti;manual", - "freemarker.cache;StringTemplateLoader;true;putTemplate;;;Argument[1];ssti;manual", - "com.mitchellbosecke.pebble;PebbleEngine;true;getTemplate;;;Argument[0];ssti;manual", - "com.mitchellbosecke.pebble;PebbleEngine;true;getLiteralTemplate;;;Argument[0];ssti;manual", - "com.hubspot.jinjava;Jinjava;true;renderForResult;;;Argument[0];ssti;manual", - "com.hubspot.jinjava;Jinjava;true;render;;;Argument[0];ssti;manual", - "org.thymeleaf;ITemplateEngine;true;process;;;Argument[0];ssti;manual", - "org.thymeleaf;ITemplateEngine;true;processThrottled;;;Argument[0];ssti;manual", - "org.apache.velocity.app;Velocity;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.app;Velocity;true;mergeTemplate;;;Argument[2];ssti;manual", - "org.apache.velocity.app;VelocityEngine;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.app;VelocityEngine;true;mergeTemplate;;;Argument[2];ssti;manual", - "org.apache.velocity.runtime.resource.util;StringResourceRepository;true;putStringResource;;;Argument[1];ssti;manual", - "org.apache.velocity.runtime;RuntimeServices;true;evaluate;;;Argument[3];ssti;manual", - "org.apache.velocity.runtime;RuntimeServices;true;parse;;;Argument[0];ssti;manual", - "org.apache.velocity.runtime;RuntimeSingleton;true;parse;;;Argument[0];ssti;manual" - ] - } -} diff --git a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll index b362a5dceeb..0bc76e384d1 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll @@ -1,7 +1,6 @@ /** Provides taint tracking configurations to be used in unsafe content URI resolution queries. */ import java -import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.UnsafeContentUriResolution diff --git a/java/ql/lib/semmle/code/java/security/XPath.qll b/java/ql/lib/semmle/code/java/security/XPath.qll index 2122093a05c..c8b1077990d 100644 --- a/java/ql/lib/semmle/code/java/security/XPath.qll +++ b/java/ql/lib/semmle/code/java/security/XPath.qll @@ -10,38 +10,6 @@ private import semmle.code.java.dataflow.ExternalFlow */ abstract class XPathInjectionSink extends DataFlow::Node { } -/** CSV sink models representing methods susceptible to XPath Injection attacks. */ -private class DefaultXPathInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.xml.xpath;XPath;true;evaluate;;;Argument[0];xpath;manual", - "javax.xml.xpath;XPath;true;evaluateExpression;;;Argument[0];xpath;manual", - "javax.xml.xpath;XPath;true;compile;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;selectObject;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;selectNodes;;;Argument[0..1];xpath;manual", - "org.dom4j;Node;true;selectSingleNode;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;numberValueOf;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;valueOf;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;matches;;;Argument[0];xpath;manual", - "org.dom4j;Node;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentFactory;true;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createPattern;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createXPath;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;selectNodes;;;Argument[0];xpath;manual", - "org.dom4j;DocumentHelper;false;sort;;;Argument[1];xpath;manual", - "org.dom4j.tree;AbstractNode;true;createXPathFilter;;;Argument[0];xpath;manual", - "org.dom4j.tree;AbstractNode;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createPattern;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createXPath;;;Argument[0];xpath;manual", - "org.dom4j.util;ProxyDocumentFactory;true;createXPathFilter;;;Argument[0];xpath;manual" - ] - } -} - /** A default sink representing methods susceptible to XPath Injection attacks. */ private class DefaultXPathInjectionSink extends XPathInjectionSink { DefaultXPathInjectionSink() { diff --git a/java/ql/lib/semmle/code/java/security/XsltInjection.qll b/java/ql/lib/semmle/code/java/security/XsltInjection.qll index 570a7575af3..f6953a09539 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjection.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjection.qll @@ -15,20 +15,6 @@ private class DefaultXsltInjectionSink extends XsltInjectionSink { DefaultXsltInjectionSink() { sinkNode(this, "xslt") } } -private class DefaultXsltInjectionSinkModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "javax.xml.transform;Transformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;XsltTransformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;transform;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;applyTemplates;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;callFunction;;;Argument[-1];xslt;manual", - "net.sf.saxon.s9api;Xslt30Transformer;false;callTemplate;;;Argument[-1];xslt;manual" - ] - } -} - /** * A unit class for adding additional taint steps. * diff --git a/java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll b/java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll new file mode 100644 index 00000000000..46df3a3ca7b --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll @@ -0,0 +1,21 @@ +/** + * INTERNAL: Do not use. + * + * Provides predicates for recommended encryption key sizes. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ + +/** Returns the minimum recommended key size for RSA. */ +int minSecureKeySizeRsa() { result = 2048 } + +/** Returns the minimum recommended key size for DSA. */ +int minSecureKeySizeDsa() { result = 2048 } + +/** Returns the minimum recommended key size for DH. */ +int minSecureKeySizeDh() { result = 2048 } + +/** Returns the minimum recommended key size for elliptic curve cryptography. */ +int minSecureKeySizeEcc() { result = 256 } + +/** Returns the minimum recommended key size for AES. */ +int minSecureKeySizeAes() { result = 128 } diff --git a/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll b/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll index 4a608890249..d0a08dc88bf 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll @@ -62,284 +62,7 @@ * a suffix `x` (possible empty) that is most likely __not__ accepted. */ -import NfaUtils - -/** - * Holds if state `s` might be inside a backtracking repetition. - */ -pragma[noinline] -private predicate stateInsideBacktracking(State s) { - s.getRepr().getParent*() instanceof MaybeBacktrackingRepetition -} - -/** - * A infinitely repeating quantifier that might backtrack. - */ -private class MaybeBacktrackingRepetition extends InfiniteRepetitionQuantifier { - MaybeBacktrackingRepetition() { - exists(RegExpTerm child | - child instanceof RegExpAlt or - child instanceof RegExpQuantifier - | - child.getParent+() = this - ) - } -} - -/** - * A state in the product automaton. - */ -private newtype TStatePair = - /** - * We lazily only construct those states that we are actually - * going to need: `(q, q)` for every fork state `q`, and any - * pair of states that can be reached from a pair that we have - * already constructed. To cut down on the number of states, - * we only represent states `(q1, q2)` where `q1` is lexicographically - * no bigger than `q2`. - * - * States are only constructed if both states in the pair are - * inside a repetition that might backtrack. - */ - MkStatePair(State q1, State q2) { - isFork(q1, _, _, _, _) and q2 = q1 - or - (step(_, _, _, q1, q2) or step(_, _, _, q2, q1)) and - rankState(q1) <= rankState(q2) - } - -/** - * Gets a unique number for a `state`. - * Is used to create an ordering of states, where states with the same `toString()` will be ordered differently. - */ -private int rankState(State state) { - state = - rank[result](State s, Location l | - stateInsideBacktracking(s) and - l = s.getRepr().getLocation() - | - s order by l.getStartLine(), l.getStartColumn(), s.toString() - ) -} - -/** - * A state in the product automaton. - */ -private class StatePair extends TStatePair { - State q1; - State q2; - - StatePair() { this = MkStatePair(q1, q2) } - - /** Gets a textual representation of this element. */ - string toString() { result = "(" + q1 + ", " + q2 + ")" } - - /** Gets the first component of the state pair. */ - State getLeft() { result = q1 } - - /** Gets the second component of the state pair. */ - State getRight() { result = q2 } -} - -/** - * Holds for `(fork, fork)` state pairs when `isFork(fork, _, _, _, _)` holds. - * - * Used in `statePairDistToFork` - */ -private predicate isStatePairFork(StatePair p) { - exists(State fork | p = MkStatePair(fork, fork) and isFork(fork, _, _, _, _)) -} - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r`. - * - * Used in `statePairDistToFork` - */ -private predicate reverseStep(StatePair r, StatePair q) { step(q, _, _, r) } - -/** - * Gets the minimum length of a path from `q` to `r` in the - * product automaton. - */ -private int statePairDistToFork(StatePair q, StatePair r) = - shortestDistances(isStatePairFork/1, reverseStep/2)(r, q, result) - -/** - * Holds if there are transitions from `q` to `r1` and from `q` to `r2` - * labelled with `s1` and `s2`, respectively, where `s1` and `s2` do not - * trivially have an empty intersection. - * - * This predicate only holds for states associated with regular expressions - * that have at least one repetition quantifier in them (otherwise the - * expression cannot be vulnerable to ReDoS attacks anyway). - */ -pragma[noopt] -private predicate isFork(State q, InputSymbol s1, InputSymbol s2, State r1, State r2) { - stateInsideBacktracking(q) and - exists(State q1, State q2 | - q1 = epsilonSucc*(q) and - delta(q1, s1, r1) and - q2 = epsilonSucc*(q) and - delta(q2, s2, r2) and - // Use pragma[noopt] to prevent intersect(s1,s2) from being the starting point of the join. - // From (s1,s2) it would find a huge number of intermediate state pairs (q1,q2) originating from different literals, - // and discover at the end that no `q` can reach both `q1` and `q2` by epsilon transitions. - exists(intersect(s1, s2)) - | - s1 != s2 - or - r1 != r2 - or - r1 = r2 and q1 != q2 - or - // If q can reach itself by epsilon transitions, then there are two distinct paths to the q1/q2 state: - // one that uses the loop and one that doesn't. The engine will separately attempt to match with each path, - // despite ending in the same state. The "fork" thus arises from the choice of whether to use the loop or not. - // To avoid every state in the loop becoming a fork state, - // we arbitrarily pick the InfiniteRepetitionQuantifier state as the canonical fork state for the loop - // (every epsilon-loop must contain such a state). - // - // We additionally require that the there exists another InfiniteRepetitionQuantifier `mid` on the path from `q` to itself. - // This is done to avoid flagging regular expressions such as `/(a?)*b/` - that only has polynomial runtime, and is detected by `js/polynomial-redos`. - // The below code is therefore a heuristic, that only flags regular expressions such as `/(a*)*b/`, - // and does not flag regular expressions such as `/(a?b?)c/`, but the latter pattern is not used frequently. - r1 = r2 and - q1 = q2 and - epsilonSucc+(q) = q and - exists(RegExpTerm term | term = q.getRepr() | term instanceof InfiniteRepetitionQuantifier) and - // One of the mid states is an infinite quantifier itself - exists(State mid, RegExpTerm term | - mid = epsilonSucc+(q) and - term = mid.getRepr() and - term instanceof InfiniteRepetitionQuantifier and - q = epsilonSucc+(mid) and - not mid = q - ) - ) and - stateInsideBacktracking(r1) and - stateInsideBacktracking(r2) -} - -/** - * Gets the state pair `(q1, q2)` or `(q2, q1)`; note that only - * one or the other is defined. - */ -private StatePair mkStatePair(State q1, State q2) { - result = MkStatePair(q1, q2) or result = MkStatePair(q2, q1) -} - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r` labelled with `s1` and `s2`, respectively. - */ -private predicate step(StatePair q, InputSymbol s1, InputSymbol s2, StatePair r) { - exists(State r1, State r2 | step(q, s1, s2, r1, r2) and r = mkStatePair(r1, r2)) -} - -/** - * Holds if there are transitions from the components of `q` to `r1` and `r2` - * labelled with `s1` and `s2`, respectively. - * - * We only consider transitions where the resulting states `(r1, r2)` are both - * inside a repetition that might backtrack. - */ -pragma[noopt] -private predicate step(StatePair q, InputSymbol s1, InputSymbol s2, State r1, State r2) { - exists(State q1, State q2 | q.getLeft() = q1 and q.getRight() = q2 | - deltaClosed(q1, s1, r1) and - deltaClosed(q2, s2, r2) and - // use noopt to force the join on `intersect` to happen last. - exists(intersect(s1, s2)) - ) and - stateInsideBacktracking(r1) and - stateInsideBacktracking(r2) -} - -private newtype TTrace = - Nil() or - Step(InputSymbol s1, InputSymbol s2, TTrace t) { isReachableFromFork(_, _, s1, s2, t, _) } - -/** - * A list of pairs of input symbols that describe a path in the product automaton - * starting from some fork state. - */ -private class Trace extends TTrace { - /** Gets a textual representation of this element. */ - string toString() { - this = Nil() and result = "Nil()" - or - exists(InputSymbol s1, InputSymbol s2, Trace t | this = Step(s1, s2, t) | - result = "Step(" + s1 + ", " + s2 + ", " + t + ")" - ) - } -} - -/** - * Holds if `r` is reachable from `(fork, fork)` under input `w`, and there is - * a path from `r` back to `(fork, fork)` with `rem` steps. - */ -private predicate isReachableFromFork(State fork, StatePair r, Trace w, int rem) { - exists(InputSymbol s1, InputSymbol s2, Trace v | - isReachableFromFork(fork, r, s1, s2, v, rem) and - w = Step(s1, s2, v) - ) -} - -private predicate isReachableFromFork( - State fork, StatePair r, InputSymbol s1, InputSymbol s2, Trace v, int rem -) { - // base case - exists(State q1, State q2 | - isFork(fork, s1, s2, q1, q2) and - r = MkStatePair(q1, q2) and - v = Nil() and - rem = statePairDistToFork(r, MkStatePair(fork, fork)) - ) - or - // recursive case - exists(StatePair p | - isReachableFromFork(fork, p, v, rem + 1) and - step(p, s1, s2, r) and - rem = statePairDistToFork(r, MkStatePair(fork, fork)) - ) -} - -/** - * Gets a state in the product automaton from which `(fork, fork)` is - * reachable in zero or more epsilon transitions. - */ -private StatePair getAForkPair(State fork) { - isFork(fork, _, _, _, _) and - result = MkStatePair(epsilonPred*(fork), epsilonPred*(fork)) -} - -/** An implementation of a chain containing chars for use by `Concretizer`. */ -private module CharTreeImpl implements CharTree { - class CharNode = Trace; - - CharNode getPrev(CharNode t) { t = Step(_, _, result) } - - /** Holds if `n` is a trace that is used by `concretize` in `isPumpable`. */ - predicate isARelevantEnd(CharNode n) { - exists(State f | isReachableFromFork(f, getAForkPair(f), n, _)) - } - - string getChar(CharNode t) { - exists(InputSymbol s1, InputSymbol s2 | t = Step(s1, s2, _) | result = intersect(s1, s2)) - } -} - -/** - * Holds if `fork` is a pumpable fork with word `w`. - */ -private predicate isPumpable(State fork, string w) { - exists(StatePair q, Trace t | - isReachableFromFork(fork, q, t, _) and - q = getAForkPair(fork) and - w = Concretizer::concretize(t) - ) -} - -/** Holds if `state` has exponential ReDoS */ -predicate hasReDoSResult = ReDoSPruning::hasReDoSResult/4; +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// ExponentialBackTracking should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.ExponentialBackTracking::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll index 5ff0cb6a39e..3b69ecc7120 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -7,1332 +7,7 @@ * other queries that benefit from reasoning about NFAs. */ -import NfaUtilsSpecific - -/** - * Gets the char after `c` (from a simplified ASCII table). - */ -private string nextChar(string c) { exists(int code | code = ascii(c) | code + 1 = ascii(result)) } - -/** - * Gets an approximation for the ASCII code for `char`. - * Only the easily printable chars are included (so no newline, tab, null, etc). - */ -private int ascii(string char) { - char = - rank[result](string c | - c = - "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" - .charAt(_) - ) -} - -/** - * Holds if `t` matches at least an epsilon symbol. - * - * That is, this term does not restrict the language of the enclosing regular expression. - * - * This is implemented as an under-approximation, and this predicate does not hold for sub-patterns in particular. - */ -predicate matchesEpsilon(RegExpTerm t) { - t instanceof RegExpStar - or - t instanceof RegExpOpt - or - t.(RegExpRange).getLowerBound() = 0 - or - exists(RegExpTerm child | - child = t.getAChild() and - matchesEpsilon(child) - | - t instanceof RegExpAlt or - t instanceof RegExpGroup or - t instanceof RegExpPlus or - t instanceof RegExpRange - ) - or - matchesEpsilon(t.(RegExpBackRef).getGroup()) - or - forex(RegExpTerm child | child = t.(RegExpSequence).getAChild() | matchesEpsilon(child)) -} - -/** - * A lookahead/lookbehind that matches the empty string. - */ -class EmptyPositiveSubPattern extends RegExpSubPattern { - EmptyPositiveSubPattern() { - ( - this instanceof RegExpPositiveLookahead - or - this instanceof RegExpPositiveLookbehind - ) and - matchesEpsilon(this.getOperand()) - } -} - -/** DEPRECATED: Use `EmptyPositiveSubPattern` instead. */ -deprecated class EmptyPositiveSubPatttern = EmptyPositiveSubPattern; - -/** - * A branch in a disjunction that is the root node in a literal, or a literal - * whose root node is not a disjunction. - */ -class RegExpRoot extends RegExpTerm { - RegExpRoot() { - exists(RegExpParent parent | - exists(RegExpAlt alt | - alt.isRootTerm() and - this = alt.getAChild() and - parent = alt.getParent() - ) - or - this.isRootTerm() and - not this instanceof RegExpAlt and - parent = this.getParent() - ) - } - - /** - * Holds if this root term is relevant to the ReDoS analysis. - */ - predicate isRelevant() { - // is actually used as a RegExp - this.isUsedAsRegExp() and - // not excluded for library specific reasons - not isExcluded(this.getRootTerm().getParent()) - } -} - -/** - * A constant in a regular expression that represents valid Unicode character(s). - */ -private class RegexpCharacterConstant extends RegExpConstant { - RegexpCharacterConstant() { this.isCharacter() } -} - -/** - * A regexp term that is relevant for this ReDoS analysis. - */ -class RelevantRegExpTerm extends RegExpTerm { - RelevantRegExpTerm() { getRoot(this).isRelevant() } -} - -/** - * Holds if `term` is the chosen canonical representative for all terms with string representation `str`. - * The string representation includes which flags are used with the regular expression. - * - * Using canonical representatives gives a huge performance boost when working with tuples containing multiple `InputSymbol`s. - * The number of `InputSymbol`s is decreased by 3 orders of magnitude or more in some larger benchmarks. - */ -private predicate isCanonicalTerm(RelevantRegExpTerm term, string str) { - term = - min(RelevantRegExpTerm t, Location loc, File file | - loc = t.getLocation() and - file = t.getFile() and - str = getCanonicalizationString(t) - | - t order by t.getFile().getRelativePath(), loc.getStartLine(), loc.getStartColumn() - ) -} - -/** - * Gets a string representation of `term` that is used for canonicalization. - */ -private string getCanonicalizationString(RelevantRegExpTerm term) { - exists(string ignoreCase | - (if RegExpFlags::isIgnoreCase(term.getRootTerm()) then ignoreCase = "i" else ignoreCase = "") and - result = term.getRawValue() + "|" + ignoreCase - ) -} - -/** - * An abstract input symbol, representing a set of concrete characters. - */ -private newtype TInputSymbol = - /** An input symbol corresponding to character `c`. */ - Char(string c) { - c = - any(RegexpCharacterConstant cc | - cc instanceof RelevantRegExpTerm and - not RegExpFlags::isIgnoreCase(cc.getRootTerm()) - ).getValue().charAt(_) - or - // normalize everything to lower case if the regexp is case insensitive - c = - any(RegexpCharacterConstant cc, string char | - cc instanceof RelevantRegExpTerm and - RegExpFlags::isIgnoreCase(cc.getRootTerm()) and - char = cc.getValue().charAt(_) - | - char.toLowerCase() - ) - } or - /** - * An input symbol representing all characters matched by - * a (non-universal) character class that has string representation `charClassString`. - */ - CharClass(string charClassString) { - exists(RelevantRegExpTerm recc | isCanonicalTerm(recc, charClassString) | - recc instanceof RegExpCharacterClass and - not recc.(RegExpCharacterClass).isUniversalClass() - or - isEscapeClass(recc, _) - ) - } or - /** An input symbol representing all characters matched by `.`. */ - Dot() or - /** An input symbol representing all characters. */ - Any() or - /** An epsilon transition in the automaton. */ - Epsilon() - -/** - * Gets the the CharClass corresponding to the canonical representative `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. - */ -private predicate sharesRoot(InputSymbol a, InputSymbol b) { - exists(RegExpRoot root | - belongsTo(a, root) and - belongsTo(b, root) - ) -} - -/** - * Holds if the `a` is an input symbol from a regexp that has root `root`. - */ -private predicate belongsTo(InputSymbol a, RegExpRoot root) { - exists(State s | getRoot(s.getRepr()) = root | - delta(s, a, _) - or - delta(_, a, s) - ) -} - -/** - * An abstract input symbol, representing a set of concrete characters. - */ -class InputSymbol extends TInputSymbol { - InputSymbol() { not this instanceof Epsilon } - - /** - * Gets a string representation of this input symbol. - */ - string toString() { - this = Char(result) - or - this = CharClass(result) - or - this = Dot() and result = "." - or - this = Any() and result = "[^]" - } -} - -/** - * An abstract input symbol that represents a character class. - */ -abstract class CharacterClass extends InputSymbol { - /** - * Gets a character that is relevant for intersection-tests involving this - * character class. - * - * Specifically, this is any of the characters mentioned explicitly in the - * character class, offset by one if it is inverted. For character class escapes, - * the result is as if the class had been written out as a series of intervals. - * - * This set is large enough to ensure that for any two intersecting character - * classes, one contains a relevant character from the other. - */ - abstract string getARelevantChar(); - - /** - * Holds if this character class matches `char`. - */ - bindingset[char] - abstract predicate matches(string char); - - /** - * Gets a character matched by this character class. - */ - string choose() { result = this.getARelevantChar() and this.matches(result) } -} - -/** - * Provides implementations for `CharacterClass`. - */ -private module CharacterClasses { - /** - * Holds if the character class `cc` has a child (constant or range) that matches `char`. - */ - pragma[noinline] - predicate hasChildThatMatches(RegExpCharacterClass cc, string char) { - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then - // normalize everything to lower case if the regexp is case insensitive - exists(string c | hasChildThatMatchesIgnoringCasingFlags(cc, c) | char = c.toLowerCase()) - else hasChildThatMatchesIgnoringCasingFlags(cc, char) - } - - /** - * Holds if the character class `cc` has a child (constant or range) that matches `char`. - * Ignores whether the character class is inside a regular expression that has the ignore case flag. - */ - pragma[noinline] - predicate hasChildThatMatchesIgnoringCasingFlags(RegExpCharacterClass cc, string char) { - exists(getCharClassForCanonicalTerm(cc)) and - exists(RegExpTerm child | child = cc.getAChild() | - char = child.(RegexpCharacterConstant).getValue() - or - rangeMatchesOnLetterOrDigits(child, char) - or - not rangeMatchesOnLetterOrDigits(child, _) and - char = getARelevantChar() and - exists(string lo, string hi | child.(RegExpCharacterRange).isRange(lo, hi) | - lo <= char and - char <= hi - ) - or - exists(string charClass | isEscapeClass(child, charClass) | - charClass.toLowerCase() = charClass and - classEscapeMatches(charClass, char) - or - char = getARelevantChar() and - charClass.toUpperCase() = charClass and - not classEscapeMatches(charClass, char) - ) - ) - } - - /** - * Holds if `range` is a range on lower-case, upper-case, or digits, and matches `char`. - * This predicate is used to restrict the searchspace for ranges by only joining `getAnyPossiblyMatchedChar` - * on a few ranges. - */ - private predicate rangeMatchesOnLetterOrDigits(RegExpCharacterRange range, string char) { - exists(string lo, string hi | - range.isRange(lo, hi) and lo = lowercaseLetter() and hi = lowercaseLetter() - | - lo <= char and - char <= hi and - char = lowercaseLetter() - ) - or - exists(string lo, string hi | - range.isRange(lo, hi) and lo = upperCaseLetter() and hi = upperCaseLetter() - | - lo <= char and - char <= hi and - char = upperCaseLetter() - ) - or - exists(string lo, string hi | range.isRange(lo, hi) and lo = digit() and hi = digit() | - lo <= char and - char <= hi and - char = digit() - ) - } - - private string lowercaseLetter() { result = "abcdefghijklmnopqrstuvwxyz".charAt(_) } - - private string upperCaseLetter() { result = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(_) } - - private string digit() { result = [0 .. 9].toString() } - - /** - * Gets a char that could be matched by a regular expression. - * Includes all printable ascii chars, all constants mentioned in a regexp, and all chars matches by the regexp `/\s|\d|\w/`. - */ - string getARelevantChar() { - exists(ascii(result)) - or - exists(RegexpCharacterConstant c | result = c.getValue().charAt(_)) - or - classEscapeMatches(_, result) - } - - /** - * Gets a char that is mentioned in the character class `c`. - */ - private string getAMentionedChar(RegExpCharacterClass c) { - exists(RegExpTerm child | child = c.getAChild() | - result = child.(RegexpCharacterConstant).getValue() - or - child.(RegExpCharacterRange).isRange(result, _) - or - child.(RegExpCharacterRange).isRange(_, result) - or - exists(string charClass | isEscapeClass(child, charClass) | - result = min(string s | classEscapeMatches(charClass.toLowerCase(), s)) - or - result = max(string s | classEscapeMatches(charClass.toLowerCase(), s)) - ) - ) - } - - bindingset[char, cc] - private string caseNormalize(string char, RegExpTerm cc) { - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then result = char.toLowerCase() - else result = char - } - - /** - * An implementation of `CharacterClass` for positive (non inverted) character classes. - */ - private class PositiveCharacterClass extends CharacterClass { - RegExpCharacterClass cc; - - PositiveCharacterClass() { this = getCharClassForCanonicalTerm(cc) and not cc.isInverted() } - - override string getARelevantChar() { result = caseNormalize(getAMentionedChar(cc), cc) } - - override predicate matches(string char) { hasChildThatMatches(cc, char) } - } - - /** - * An implementation of `CharacterClass` for inverted character classes. - */ - private class InvertedCharacterClass extends CharacterClass { - RegExpCharacterClass cc; - - InvertedCharacterClass() { this = getCharClassForCanonicalTerm(cc) and cc.isInverted() } - - override string getARelevantChar() { - result = nextChar(caseNormalize(getAMentionedChar(cc), cc)) or - nextChar(result) = caseNormalize(getAMentionedChar(cc), cc) - } - - bindingset[char] - override predicate matches(string char) { not hasChildThatMatches(cc, char) } - } - - /** - * Holds if the character class escape `clazz` (\d, \s, or \w) matches `char`. - */ - pragma[noinline] - private predicate classEscapeMatches(string clazz, string char) { - clazz = "d" and - char = "0123456789".charAt(_) - or - clazz = "s" and - char = [" ", "\t", "\r", "\n", 11.toUnicode(), 12.toUnicode()] // 11.toUnicode() = \v, 12.toUnicode() = \f - or - clazz = "w" and - char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".charAt(_) - } - - /** - * An implementation of `CharacterClass` for \d, \s, and \w. - */ - private class PositiveCharacterClassEscape extends CharacterClass { - string charClass; - RegExpTerm cc; - - PositiveCharacterClassEscape() { - isEscapeClass(cc, charClass) and - this = getCharClassForCanonicalTerm(cc) and - charClass = ["d", "s", "w"] - } - - override string getARelevantChar() { - charClass = "d" and - result = ["0", "9"] - or - charClass = "s" and - result = " " - or - charClass = "w" and - if RegExpFlags::isIgnoreCase(cc.getRootTerm()) - then result = ["a", "z", "_", "0", "9"] - else result = ["a", "Z", "_", "0", "9"] - } - - override predicate matches(string char) { classEscapeMatches(charClass, char) } - - override string choose() { - charClass = "d" and - result = "9" - or - charClass = "s" and - result = " " - or - charClass = "w" and - result = "a" - } - } - - /** - * An implementation of `CharacterClass` for \D, \S, and \W. - */ - private class NegativeCharacterClassEscape extends CharacterClass { - string charClass; - - NegativeCharacterClassEscape() { - exists(RegExpTerm cc | - isEscapeClass(cc, charClass) and - this = getCharClassForCanonicalTerm(cc) and - charClass = ["D", "S", "W"] - ) - } - - override string getARelevantChar() { - charClass = "D" and - result = ["a", "Z", "!"] - or - charClass = "S" and - result = ["a", "9", "!"] - or - charClass = "W" and - result = [" ", "!"] - } - - bindingset[char] - override predicate matches(string char) { - not classEscapeMatches(charClass.toLowerCase(), char) - } - } - - /** Gets a representative for all char classes that match the same chars as `c`. */ - CharacterClass normalize(CharacterClass c) { - exists(string normalization | - normalization = getNormalizationString(c) and - result = - min(CharacterClass cc, string raw | - getNormalizationString(cc) = normalization and cc = CharClass(raw) - | - cc order by raw - ) - ) - } - - /** Gets a string representing all the chars matched by `c` */ - private string getNormalizationString(CharacterClass c) { - (c instanceof PositiveCharacterClass or c instanceof PositiveCharacterClassEscape) and - result = concat(string char | c.matches(char) and char = CharacterClasses::getARelevantChar()) - or - (c instanceof InvertedCharacterClass or c instanceof NegativeCharacterClassEscape) and - // the string produced by the concat can not contain repeated chars - // so by starting the below with "nn" we can guarantee that - // it will not overlap with the above case. - // and a negative char class can never match the same chars as a positive one, so we don't miss any results from this. - result = - "nn:" + - concat(string char | not c.matches(char) and char = CharacterClasses::getARelevantChar()) - } -} - -private class EdgeLabel extends TInputSymbol { - string toString() { - this = Epsilon() and result = "" - or - exists(InputSymbol s | this = s and result = s.toString()) - } -} - -/** - * A RegExp term that acts like a plus. - * Either it's a RegExpPlus, or it is a range {1,X} where X is >= 30. - * 30 has been chosen as a threshold because for exponential blowup 2^30 is enough to get a decent DOS attack. - */ -private class EffectivelyPlus extends RegExpTerm { - EffectivelyPlus() { - this instanceof RegExpPlus - or - exists(RegExpRange range | - range.getLowerBound() = 1 and - (range.getUpperBound() >= 30 or not exists(range.getUpperBound())) - | - this = range - ) - } -} - -/** - * A RegExp term that acts like a star. - * Either it's a RegExpStar, or it is a range {0,X} where X is >= 30. - */ -private class EffectivelyStar extends RegExpTerm { - EffectivelyStar() { - this instanceof RegExpStar - or - exists(RegExpRange range | - range.getLowerBound() = 0 and - (range.getUpperBound() >= 30 or not exists(range.getUpperBound())) - | - this = range - ) - } -} - -/** - * A RegExp term that acts like a question mark. - * Either it's a RegExpQuestion, or it is a range {0,1}. - */ -private class EffectivelyQuestion extends RegExpTerm { - EffectivelyQuestion() { - this instanceof RegExpOpt - or - exists(RegExpRange range | range.getLowerBound() = 0 and range.getUpperBound() = 1 | - this = range - ) - } -} - -/** - * Gets the state before matching `t`. - */ -pragma[inline] -private State before(RegExpTerm t) { result = Match(t, 0) } - -/** - * Gets a state the NFA may be in after matching `t`. - */ -State after(RegExpTerm t) { - exists(RegExpAlt alt | t = alt.getAChild() | result = after(alt)) - or - exists(RegExpSequence seq, int i | t = seq.getChild(i) | - result = before(seq.getChild(i + 1)) - or - i + 1 = seq.getNumChild() and result = after(seq) - ) - or - exists(RegExpGroup grp | t = grp.getAChild() | result = after(grp)) - or - exists(EffectivelyStar star | t = star.getAChild() | - not isPossessive(star) and - result = before(star) - ) - or - exists(EffectivelyPlus plus | t = plus.getAChild() | - not isPossessive(plus) and - result = before(plus) - or - result = after(plus) - ) - or - exists(EffectivelyQuestion opt | t = opt.getAChild() | result = after(opt)) - or - exists(RegExpRoot root | t = root | - if matchesAnySuffix(root) then result = AcceptAnySuffix(root) else result = Accept(root) - ) -} - -/** - * Holds if the NFA has a transition from `q1` to `q2` labelled with `lbl`. - */ -predicate delta(State q1, EdgeLabel lbl, State q2) { - exists(RegexpCharacterConstant s, int i | - q1 = Match(s, i) and - ( - not RegExpFlags::isIgnoreCase(s.getRootTerm()) and - lbl = Char(s.getValue().charAt(i)) - or - // normalize everything to lower case if the regexp is case insensitive - RegExpFlags::isIgnoreCase(s.getRootTerm()) and - exists(string c | c = s.getValue().charAt(i) | lbl = Char(c.toLowerCase())) - ) and - ( - q2 = Match(s, i + 1) - or - s.getValue().length() = i + 1 and - q2 = after(s) - ) - ) - or - exists(RegExpDot dot | q1 = before(dot) and q2 = after(dot) | - if RegExpFlags::isDotAll(dot.getRootTerm()) then lbl = Any() else lbl = Dot() - ) - or - exists(RegExpCharacterClass cc | - cc.isUniversalClass() and q1 = before(cc) and lbl = Any() and q2 = after(cc) - or - q1 = before(cc) 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(getCanonicalizationString(cc))) and - q2 = after(cc) - ) - or - exists(RegExpAlt alt | lbl = Epsilon() | q1 = before(alt) and q2 = before(alt.getAChild())) - or - exists(RegExpSequence seq | lbl = Epsilon() | q1 = before(seq) and q2 = before(seq.getChild(0))) - or - exists(RegExpGroup grp | lbl = Epsilon() | q1 = before(grp) and q2 = before(grp.getChild(0))) - or - exists(EffectivelyStar star | lbl = Epsilon() | - q1 = before(star) and q2 = before(star.getChild(0)) - or - q1 = before(star) and q2 = after(star) - ) - or - exists(EffectivelyPlus plus | lbl = Epsilon() | - q1 = before(plus) and q2 = before(plus.getChild(0)) - ) - or - exists(EffectivelyQuestion opt | lbl = Epsilon() | - q1 = before(opt) and q2 = before(opt.getChild(0)) - or - q1 = before(opt) and q2 = after(opt) - ) - or - exists(RegExpRoot root | q1 = AcceptAnySuffix(root) | - lbl = Any() and q2 = q1 - or - lbl = Epsilon() and q2 = Accept(root) - ) - or - exists(RegExpRoot root | q1 = Match(root, 0) | matchesAnyPrefix(root) and lbl = Any() and q2 = q1) - or - exists(RegExpDollar dollar | q1 = before(dollar) | - lbl = Epsilon() and q2 = Accept(getRoot(dollar)) - ) - or - exists(EmptyPositiveSubPattern empty | q1 = before(empty) | lbl = Epsilon() and q2 = after(empty)) -} - -/** - * Gets a state that `q` has an epsilon transition to. - */ -State epsilonSucc(State q) { delta(q, Epsilon(), result) } - -/** - * Gets a state that has an epsilon transition to `q`. - */ -State epsilonPred(State q) { q = epsilonSucc(result) } - -/** - * Holds if there is a state `q` that can be reached from `q1` - * along epsilon edges, such that there is a transition from - * `q` to `q2` that consumes symbol `s`. - */ -predicate deltaClosed(State q1, InputSymbol s, State q2) { delta(epsilonSucc*(q1), s, q2) } - -/** - * Gets the root containing the given term, that is, the root of the literal, - * or a branch of the root disjunction. - */ -RegExpRoot getRoot(RegExpTerm term) { - result = term or - result = getRoot(term.getParent()) -} - -/** - * A state in the NFA. - */ -newtype TState = - /** - * A state representing that the NFA is about to match a term. - * `i` is used to index into multi-char literals. - */ - Match(RelevantRegExpTerm t, int i) { - i = 0 - or - exists(t.(RegexpCharacterConstant).getValue().charAt(i)) - } or - /** - * An accept state, where exactly the given input string is accepted. - */ - Accept(RegExpRoot l) { l.isRelevant() } or - /** - * An accept state, where the given input string, or any string that has this - * string as a prefix, is accepted. - */ - AcceptAnySuffix(RegExpRoot l) { l.isRelevant() } - -/** - * Gets a state that is about to match the regular expression `t`. - */ -State mkMatch(RegExpTerm t) { result = Match(t, 0) } - -/** - * A state in the NFA corresponding to a regular expression. - * - * Each regular expression literal `l` has one accepting state - * `Accept(l)`, one state that accepts all suffixes `AcceptAnySuffix(l)`, - * and a state `Match(t, i)` for every subterm `t`, - * which represents the state of the NFA before starting to - * match `t`, or the `i`th character in `t` if `t` is a constant. - */ -class State extends TState { - RegExpTerm repr; - - State() { - this = Match(repr, _) or - this = Accept(repr) or - this = AcceptAnySuffix(repr) - } - - /** - * Gets a string representation for this state in a regular expression. - */ - string toString() { - exists(int i | this = Match(repr, i) | result = "Match(" + repr + "," + i + ")") - or - this instanceof Accept and - result = "Accept(" + repr + ")" - or - this instanceof AcceptAnySuffix and - result = "AcceptAny(" + repr + ")" - } - - /** - * Gets the location for this state. - */ - Location getLocation() { result = repr.getLocation() } - - /** - * Gets the term represented by this state. - */ - RegExpTerm getRepr() { result = repr } -} - -/** - * Gets the minimum char that is matched by both the character classes `c` and `d`. - */ -private string getMinOverlapBetweenCharacterClasses(CharacterClass c, CharacterClass d) { - result = min(getAOverlapBetweenCharacterClasses(c, d)) -} - -/** - * Gets a char that is matched by both the character classes `c` and `d`. - * And `c` and `d` is not the same character class. - */ -private string getAOverlapBetweenCharacterClasses(CharacterClass c, CharacterClass d) { - sharesRoot(c, d) and - result = [c.getARelevantChar(), d.getARelevantChar()] and - c.matches(result) and - d.matches(result) and - not c = d -} - -/** - * Gets a character that is represented by both `c` and `d`. - */ -string intersect(InputSymbol c, InputSymbol d) { - (sharesRoot(c, d) or [c, d] = Any()) and - ( - c = Char(result) and - d = getAnInputSymbolMatching(result) - or - result = getMinOverlapBetweenCharacterClasses(c, d) - or - result = c.(CharacterClass).choose() and - ( - d = c - or - d = Dot() and - not (result = "\n" or result = "\r") - or - d = Any() - ) - or - (c = Dot() or c = Any()) and - (d = Dot() or d = Any()) and - result = "a" - ) - or - result = intersect(d, c) -} - -/** - * Gets a symbol that matches `char`. - */ -bindingset[char] -InputSymbol getAnInputSymbolMatching(string char) { - result = Char(char) - or - result.(CharacterClass).matches(char) - or - result = Dot() and - not (char = "\n" or char = "\r") - or - result = Any() -} - -/** - * Holds if `state` is a start state. - */ -predicate isStartState(State state) { - state = mkMatch(any(RegExpRoot r)) - or - exists(RegExpCaret car | state = after(car)) -} - -/** - * Holds if `state` is a candidate for ReDoS with string `pump`. - */ -signature predicate isCandidateSig(State state, string pump); - -/** - * Holds if `state` is a candidate for ReDoS. - */ -signature predicate isCandidateSig(State state); - -/** - * Predicates for constructing a prefix string that leads to a given state. - */ -module PrefixConstruction { - /** - * Holds if `state` is the textually last start state for the regular expression. - */ - private predicate lastStartState(RelevantState state) { - exists(RegExpRoot root | - state = - max(RelevantState s, Location l | - isStartState(s) and - getRoot(s.getRepr()) = root and - l = s.getRepr().getLocation() - | - s - order by - l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), - l.getEndLine() - ) - ) - } - - /** - * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. - */ - private predicate existsTransition(State a, State b) { delta(a, _, b) } - - /** - * Gets the minimum number of transitions it takes to reach `state` from the `start` state. - */ - int prefixLength(State start, State state) = - shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) - - /** - * Gets the minimum number of transitions it takes to reach `state` from the start state. - */ - private int lengthFromStart(State state) { result = prefixLength(_, state) } - - /** - * Gets a string for which the regular expression will reach `state`. - * - * Has at most one result for any given `state`. - * This predicate will not always have a result even if there is a ReDoS issue in - * the regular expression. - */ - string prefix(State state) { - lastStartState(state) and - result = "" - or - // the search stops past the last redos candidate state. - lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and - exists(State prev | - // select a unique predecessor (by an arbitrary measure) - prev = - min(State s, Location loc | - lengthFromStart(s) = lengthFromStart(state) - 1 and - loc = s.getRepr().getLocation() and - delta(s, _, state) - | - s - order by - loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), - s.getRepr().toString() - ) - | - // greedy search for the shortest prefix - result = prefix(prev) and delta(prev, Epsilon(), state) - or - not delta(prev, Epsilon(), state) and - result = prefix(prev) + getCanonicalEdgeChar(prev, state) - ) - } - - /** - * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. - */ - private string getCanonicalEdgeChar(State prev, State next) { - result = - min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) - } - - /** A state within a regular expression that contains a candidate state. */ - class RelevantState instanceof State { - RelevantState() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) - } - - /** Gets a string representation for this state in a regular expression. */ - string toString() { result = State.super.toString() } - - /** Gets the term represented by this state. */ - RegExpTerm getRepr() { result = State.super.getRepr() } - } -} - -/** - * A module for pruning candidate ReDoS states. - * The candidates are specified by the `isCandidate` signature predicate. - * The candidates are checked for rejecting suffixes and deduplicated, - * and the resulting ReDoS states are read by the `hasReDoSResult` predicate. - */ -module ReDoSPruning { - /** - * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking. - * No check whether a rejected suffix exists has been made. - */ - private predicate isReDoSCandidate(State state, string pump) { - isCandidate(state, pump) and - not state = acceptsAnySuffix() and // pruning early - these can never get stuck in a rejecting state. - ( - not isCandidate(epsilonSucc+(state), _) - or - epsilonSucc+(state) = state and - state = - max(State s, Location l | - s = epsilonSucc+(state) and - l = s.getRepr().getLocation() and - isCandidate(s, _) and - s.getRepr() instanceof InfiniteRepetitionQuantifier - | - s order by l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine() - ) - ) - } - - /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ - private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - - predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - - import PrefixConstruction as Prefix - - class RelevantState = Prefix::RelevantState; - - /** - * Predicates for testing the presence of a rejecting suffix. - * - * These predicates are used to ensure that the all states reached from the fork - * by repeating `w` have a rejecting suffix. - * - * For example, a regexp like `/^(a+)+/` will accept any string as long the prefix is - * some number of `"a"`s, and it is therefore not possible to construct a rejecting suffix. - * - * A regexp like `/(a+)+$/` or `/(a+)+b/` trivially has a rejecting suffix, - * as the suffix "X" will cause both the regular expressions to be rejected. - * - * The string `w` is repeated any number of times because it needs to be - * infinitely repeatable for the attack to work. - * For the regular expression `/((ab)+)*abab/` the accepting state is not reachable from the fork - * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. - */ - private module SuffixConstruction { - /** - * Holds if all states reachable from `fork` by repeating `w` - * are likely rejectable by appending some suffix. - */ - predicate reachesOnlyRejectableSuffixes(State fork, string w) { - isReDoSCandidate(fork, w) and - forex(State next | next = process(fork, w, w.length() - 1) | isLikelyRejectable(next)) and - not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened. - } - - /** - * Holds if there likely exists a suffix starting from `s` that leads to the regular expression being rejected. - * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. - */ - pragma[noinline] - private predicate isLikelyRejectable(RelevantState s) { - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - } - - /** - * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. - */ - predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } - - /** - * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. - */ - pragma[noopt] - predicate hasEdgeToLikelyRejectable(RelevantState s) { - // all edges (at least one) with some char leads to another state that is rejectable. - // the `next` states might not share a common suffix, which can cause FPs. - exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | - // noopt to force `hasEdgeToLikelyRejectableHelper` to be first in the join-order. - exists(State next | deltaClosedChar(s, char, next) | isLikelyRejectable(next)) and - forall(State next | deltaClosedChar(s, char, next) | isLikelyRejectable(next)) - ) - } - - /** - * Gets a char for there exists a transition away from `s`, - * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. - */ - pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(RelevantState s) { - not hasRejectEdge(s) and - not isRejectState(s) and - deltaClosedChar(s, result, _) - } - - /** - * Holds if there is a state `next` that can be reached from `prev` - * along epsilon edges, such that there is a transition from - * `prev` to `next` that the character symbol `char`. - */ - predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { - deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) - } - - pragma[noinline] - InputSymbol getAnInputSymbolMatchingRelevant(string char) { - char = relevant(_) and - result = getAnInputSymbolMatching(char) - } - - pragma[noinline] - RegExpRoot relevantRoot() { - exists(RegExpTerm term, State s | - s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm() - ) - } - - /** - * Gets a char used for finding possible suffixes inside `root`. - */ - pragma[noinline] - private string relevant(RegExpRoot root) { - root = relevantRoot() and - ( - exists(ascii(result)) and exists(root) - or - exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _)) - or - // The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation). - // The three chars must be kept in sync with `hasSimpleRejectEdge`. - result = ["|", "\n", "Z"] and exists(root) - ) - } - - /** - * Holds if there exists a `char` such that there is no edge from `s` labeled `char` in our NFA. - * The NFA does not model reject states, so the above is the same as saying there is a reject edge. - */ - private predicate hasRejectEdge(State s) { - hasSimpleRejectEdge(s) - or - not hasSimpleRejectEdge(s) and - exists(string char | char = relevant(getRoot(s.getRepr())) | not deltaClosedChar(s, char, _)) - } - - /** - * Holds if there is no edge from `s` labeled with "|", "\n", or "Z" in our NFA. - * This predicate is used as a cheap pre-processing to speed up `hasRejectEdge`. - */ - private predicate hasSimpleRejectEdge(State s) { - // The three chars were chosen arbitrarily. The three chars must be kept in sync with `relevant`. - exists(string char | char = ["|", "\n", "Z"] | not deltaClosedChar(s, char, _)) - } - - /** - * Gets a state that can be reached from pumpable `fork` consuming all - * chars in `w` any number of times followed by the first `i+1` characters of `w`. - */ - pragma[noopt] - private State process(State fork, string w, int i) { - exists(State prev | prev = getProcessPrevious(fork, i, w) | - not prev = acceptsAnySuffix() and // we stop `process(..)` early if we can. If the successor accepts any suffix, then we know it can never be rejected. - exists(string char, InputSymbol sym | - char = w.charAt(i) and - deltaClosed(prev, sym, result) and - // noopt to prevent joining `prev` with all possible `chars` that could transition away from `prev`. - // Instead only join with the set of `chars` where a relevant `InputSymbol` has already been found. - sym = getAProcessInputSymbol(char) - ) - ) - } - - /** - * Gets a state that can be reached from pumpable `fork` consuming all - * chars in `w` any number of times followed by the first `i` characters of `w`. - */ - private State getProcessPrevious(State fork, int i, string w) { - isReDoSCandidate(fork, w) and - ( - i = 0 and result = fork - or - result = process(fork, w, i - 1) - or - // repeat until fixpoint - i = 0 and - result = process(fork, w, w.length() - 1) - ) - } - - /** - * Gets an InputSymbol that matches `char`. - * The predicate is specialized to only have a result for the `char`s that are relevant for the `process` predicate. - */ - private InputSymbol getAProcessInputSymbol(string char) { - char = getAProcessChar() and - result = getAnInputSymbolMatching(char) - } - - /** - * Gets a `char` that occurs in a `pump` string. - */ - private string getAProcessChar() { result = any(string s | isReDoSCandidate(_, s)).charAt(_) } - } - - /** - * Holds if `term` may cause superlinear backtracking on strings containing many repetitions of `pump`. - * Gets the shortest string that causes superlinear backtracking. - */ - private predicate isReDoSAttackable(RegExpTerm term, string pump, State s) { - exists(int i, string c | s = Match(term, i) | - c = - min(string w | - isCandidate(s, w) and - SuffixConstruction::reachesOnlyRejectableSuffixes(s, w) - | - w order by w.length(), w - ) and - pump = escape(rotate(c, i)) - ) - } - - /** - * Holds if the state `s` (represented by the term `t`) can have backtracking with repetitions of `pump`. - * - * `prefixMsg` contains a friendly message for a prefix that reaches `s` (or `prefixMsg` is the empty string if the prefix is empty or if no prefix could be found). - */ - predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { - isReDoSAttackable(t, pump, s) and - ( - prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and - not Prefix::prefix(s) = "" - or - Prefix::prefix(s) = "" and prefixMsg = "" - or - not exists(Prefix::prefix(s)) and prefixMsg = "" - ) - } - - /** - * Gets the result of backslash-escaping newlines, carriage-returns and - * backslashes in `s`. - */ - bindingset[s] - private string escape(string s) { - result = - s.replaceAll("\\", "\\\\") - .replaceAll("\n", "\\n") - .replaceAll("\r", "\\r") - .replaceAll("\t", "\\t") - } - - /** - * Gets `str` with the last `i` characters moved to the front. - * - * We use this to adjust the pump string to match with the beginning of - * a RegExpTerm, so it doesn't start in the middle of a constant. - */ - bindingset[str, i] - private string rotate(string str, int i) { - result = str.suffix(str.length() - i) + str.prefix(str.length() - i) - } -} - -/** - * A module that describes a tree where each node has one or more associated characters, also known as a trie. - * The root node has no associated character. - * This module is a signature used in `Concretizer`. - */ -signature module CharTree { - /** A node in the tree. */ - class CharNode; - - /** Gets the previous node in the tree from `t`. */ - CharNode getPrev(CharNode t); - - /** - * Holds if `n` is at the end of a tree. I.e. a node that should have a result in the `Concretizer` module. - * Such a node can still have children. - */ - predicate isARelevantEnd(CharNode n); - - /** Gets a char associated with `t`. */ - string getChar(CharNode t); -} - -/** - * Implements an algorithm for computing all possible strings - * from following a tree of nodes (as described in `CharTree`). - * - * The string is build using one big concat, where all the chars are computed first. - * See `concretize`. - */ -module Concretizer { - private class Node = Impl::CharNode; - - private predicate getPrev = Impl::getPrev/1; - - private predicate isARelevantEnd = Impl::isARelevantEnd/1; - - private predicate getChar = Impl::getChar/1; - - /** Holds if `n` is on a path from the root to a leaf, and is therefore relevant for the results in `concretize`. */ - private predicate isRelevant(Node n) { - isARelevantEnd(n) - or - exists(Node succ | isRelevant(succ) | n = getPrev(succ)) - } - - /** Holds if `n` is a root with no predecessors. */ - private predicate isRoot(Node n) { not exists(getPrev(n)) } - - /** Gets the distance from a root to `n`. */ - private int nodeDepth(Node n) { - result = 0 and isRoot(n) - or - isRelevant(n) and - exists(Node prev | result = nodeDepth(prev) + 1 | prev = getPrev(n)) - } - - /** Gets an ancestor of `end`, where `end` is a node that should have a result in `concretize`. */ - private Node getAnAncestor(Node end) { isARelevantEnd(end) and result = getPrev*(end) } - - /** Gets the `i`th character on the path from the root to `n`. */ - pragma[noinline] - private string getPrefixChar(Node n, int i) { - exists(Node ancestor | - result = getChar(ancestor) and - ancestor = getAnAncestor(n) and - i = nodeDepth(ancestor) - ) - } - - /** Gets a string corresponding to `node`. */ - language[monotonicAggregates] - string concretize(Node n) { - result = strictconcat(int i | exists(getPrefixChar(n, i)) | getPrefixChar(n, i) order by i) - } -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// NfaUtils should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.NfaUtils::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll deleted file mode 100644 index 742229eacca..00000000000 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtilsSpecific.qll +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This module should provide a class hierarchy corresponding to a parse tree of regular expressions. - * This is the interface to the shared ReDoS library. - */ - -private import java -import semmle.code.FileSystem -import semmle.code.java.regex.RegexTreeView - -/** - * Holds if `term` is an escape class representing e.g. `\d`. - * `clazz` is which character class it represents, e.g. "d" for `\d`. - */ -predicate isEscapeClass(RegExpTerm term, string clazz) { - term.(RegExpCharacterClassEscape).getValue() = clazz - or - term.(RegExpNamedProperty).getBackslashEquivalent() = clazz -} - -/** - * Holds if `term` is a possessive quantifier, e.g. `a*+`. - */ -predicate isPossessive(RegExpQuantifier term) { term.isPossessive() } - -/** - * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against. - */ -predicate matchesAnyPrefix(RegExpTerm term) { not term.getRegex().matchesFullString() } - -/** - * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against. - */ -predicate matchesAnySuffix(RegExpTerm term) { not term.getRegex().matchesFullString() } - -/** - * Holds if the regular expression should not be considered. - * - * We make the pragmatic performance optimization to ignore regular expressions in files - * that do not belong to the project code (such as installed dependencies). - */ -predicate isExcluded(RegExpParent parent) { - not exists(parent.getRegex().getLocation().getFile().getRelativePath()) - or - // Regexes with many occurrences of ".*" may cause the polynomial ReDoS computation to explode, so - // we explicitly exclude these. - strictcount(int i | exists(parent.getRegex().getText().regexpFind("\\.\\*", i, _)) | i) > 10 -} - -/** - * A module containing predicates for determining which flags a regular expression have. - */ -module RegExpFlags { - /** - * Holds if `root` has the `i` flag for case-insensitive matching. - */ - predicate isIgnoreCase(RegExpTerm root) { - root.isRootTerm() and - root.getLiteral().isIgnoreCase() - } - - /** - * Gets the flags for `root`, or the empty string if `root` has no flags. - */ - deprecated string getFlags(RegExpTerm root) { - root.isRootTerm() and - result = root.getLiteral().getFlags() - } - - /** - * Holds if `root` has the `s` flag for multi-line matching. - */ - predicate isDotAll(RegExpTerm root) { - root.isRootTerm() and - root.getLiteral().isDotAll() - } -} diff --git a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll index b0a8ff1a3c5..2a822ac69de 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll @@ -1,19 +1,19 @@ /** Definitions and configurations for the Polynomial ReDoS query */ -import semmle.code.java.security.regexp.SuperlinearBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.SuperlinearBackTracking::Make as SuperlinearBackTracking import semmle.code.java.dataflow.DataFlow -import semmle.code.java.regex.RegexTreeView import semmle.code.java.regex.RegexFlowConfigs import semmle.code.java.dataflow.FlowSources /** A sink for polynomial redos queries, where a regex is matched. */ class PolynomialRedosSink extends DataFlow::Node { - RegExpLiteral reg; + TreeView::RegExpLiteral reg; PolynomialRedosSink() { regexMatchedAgainst(reg.getRegex(), this.asExpr()) } /** Gets the regex that is matched against this node. */ - RegExpTerm getRegExp() { result.getParent() = reg } + TreeView::RegExpTerm getRegExp() { result.getParent() = reg } } /** @@ -49,7 +49,8 @@ class PolynomialRedosConfig extends TaintTracking::Configuration { /** Holds if there is flow from `source` to `sink` that is matched against the regexp term `regexp` that is vulnerable to Polynomial ReDoS. */ predicate hasPolynomialReDoSResult( - DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp ) { any(PolynomialRedosConfig config).hasFlowPath(source, sink) and regexp.getRootTerm() = sink.getNode().(PolynomialRedosSink).getRegExp() diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll new file mode 100644 index 00000000000..7b96ad6e198 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjection.qll @@ -0,0 +1,48 @@ +/** Provides classes and predicates related to regex injection in Java. */ + +import java +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.frameworks.Regex + +/** A data flow sink for untrusted user input used to construct regular expressions. */ +abstract class RegexInjectionSink extends DataFlow::ExprNode { } + +/** A sanitizer for untrusted user input used to construct regular expressions. */ +abstract class RegexInjectionSanitizer extends DataFlow::ExprNode { } + +/** A method call that takes a regular expression as an argument. */ +private class DefaultRegexInjectionSink extends RegexInjectionSink { + DefaultRegexInjectionSink() { + // we only select sinks where there is direct regex creation, not regex uses + sinkNode(this, ["regex-use[]", "regex-use[f1]", "regex-use[f-1]", "regex-use[-1]", "regex-use"]) + } +} + +/** + * A call to the `Pattern.quote` method, which gives metacharacters or escape sequences + * no special meaning. + */ +private class PatternQuoteCall extends RegexInjectionSanitizer { + PatternQuoteCall() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + ma.getArgument(0) = this.asExpr() and + m instanceof PatternQuoteMethod + ) + } +} + +/** + * Use of the `Pattern.LITERAL` flag with `Pattern.compile`, which gives metacharacters + * or escape sequences no special meaning. + */ +private class PatternLiteralFlag extends RegexInjectionSanitizer { + PatternLiteralFlag() { + exists(MethodAccess ma, Method m, PatternLiteralField field | m = ma.getMethod() | + ma.getArgument(0) = this.asExpr() and + m.getDeclaringType() instanceof TypeRegexPattern and + m.hasName("compile") and + ma.getArgument(1) = field.getAnAccess() + ) + } +} diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll new file mode 100644 index 00000000000..e2453c08dca --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll @@ -0,0 +1,17 @@ +/** Provides configurations to be used in queries related to regex injection. */ + +import java +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.regexp.RegexInjection + +/** A taint-tracking configuration for untrusted user input used to construct regular expressions. */ +class RegexInjectionConfiguration extends TaintTracking::Configuration { + RegexInjectionConfiguration() { this = "RegexInjection" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexInjectionSanitizer } +} diff --git a/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll b/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll index 14a69dc0644..623b1540ef1 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll @@ -1,11 +1,4 @@ /** - * Provides classes for working with regular expressions that can - * perform backtracking in superlinear time. - */ - -import NfaUtils - -/* * This module implements the analysis described in the paper: * Valentin Wustholz, Oswaldo Olivo, Marijn J. H. Heule, and Isil Dillig: * Static Detection of DoS Vulnerabilities in @@ -42,377 +35,7 @@ import NfaUtils * It also doesn't find all transitions in the product automaton, which can cause false negatives. */ -/** - * Gets any root (start) state of a regular expression. - */ -private State getRootState() { result = mkMatch(any(RegExpRoot r)) } - -private newtype TStateTuple = - MkStateTuple(State q1, State q2, State q3) { - // starts at (pivot, pivot, succ) - isStartLoops(q1, q3) and q1 = q2 - or - step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) - } - -/** - * A state in the product automaton. - * The product automaton contains 3-tuples of states. - * - * We lazily only construct those states that we are actually - * going to need. - * Either a start state `(pivot, pivot, succ)`, or a state - * where there exists a transition from an already existing state. - * - * The exponential variant of this query (`js/redos`) uses an optimization - * trick where `q1 <= q2`. This trick cannot be used here as the order - * of the elements matter. - */ -class StateTuple extends TStateTuple { - State q1; - State q2; - State q3; - - StateTuple() { this = MkStateTuple(q1, q2, q3) } - - /** - * Gest a string representation of this tuple. - */ - string toString() { result = "(" + q1 + ", " + q2 + ", " + q3 + ")" } - - /** - * Holds if this tuple is `(r1, r2, r3)`. - */ - pragma[noinline] - predicate isTuple(State r1, State r2, State r3) { r1 = q1 and r2 = q2 and r3 = q3 } -} - -/** - * A module for determining feasible tuples for the product automaton. - * - * The implementation is split into many predicates for performance reasons. - */ -private module FeasibleTuple { - /** - * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state to an end-state in the product automaton. - */ - pragma[inline] - predicate isFeasibleTuple(State r1, State r2, State r3) { - // The first element is either inside a repetition (or the start state itself) - isRepetitionOrStart(r1) and - // The last element is inside a repetition - stateInsideRepetition(r3) and - // The states are reachable in the NFA in the order r1 -> r2 -> r3 - delta+(r1) = r2 and - delta+(r2) = r3 and - // The first element can reach a beginning (the "pivot" state in a `(pivot, succ)` pair). - canReachABeginning(r1) and - // The last element can reach a target (the "succ" state in a `(pivot, succ)` pair). - canReachATarget(r3) - } - - /** - * Holds if `s` is either inside a repetition, or is the start state (which is a repetition). - */ - pragma[noinline] - private predicate isRepetitionOrStart(State s) { stateInsideRepetition(s) or s = getRootState() } - - /** - * Holds if state `s` might be inside a backtracking repetition. - */ - pragma[noinline] - private predicate stateInsideRepetition(State s) { - s.getRepr().getParent*() instanceof InfiniteRepetitionQuantifier - } - - /** - * Holds if there exists a path in the NFA from `s` to a "pivot" state - * (from a `(pivot, succ)` pair that starts the search). - */ - pragma[noinline] - private predicate canReachABeginning(State s) { - delta+(s) = any(State pivot | isStartLoops(pivot, _)) - } - - /** - * Holds if there exists a path in the NFA from `s` to a "succ" state - * (from a `(pivot, succ)` pair that starts the search). - */ - pragma[noinline] - private predicate canReachATarget(State s) { delta+(s) = any(State succ | isStartLoops(_, succ)) } -} - -/** - * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. - * - * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != succ`. - * The case where `pivot = succ` causes exponential backtracking and is handled by the `js/redos` query. - */ -predicate isStartLoops(State pivot, State succ) { - pivot != succ and - succ.getRepr() instanceof InfiniteRepetitionQuantifier and - delta+(pivot) = succ and - ( - pivot.getRepr() instanceof InfiniteRepetitionQuantifier - or - pivot = mkMatch(any(RegExpRoot root)) - ) -} - -/** - * Gets a state for which there exists a transition in the NFA from `s'. - */ -State delta(State s) { delta(s, _, result) } - -/** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. - */ -pragma[noinline] -predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { - exists(State r1, State r2, State r3 | - step(q, s1, s2, s3, r1, r2, r3) and r = MkStateTuple(r1, r2, r3) - ) -} - -/** - * Holds if there are transitions from the components of `q` to `r1`, `r2`, and `r3 - * labelled with `s1`, `s2`, and `s3`, respectively. - */ -pragma[noopt] -predicate step( - StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, State r1, State r2, State r3 -) { - exists(State q1, State q2, State q3 | q.isTuple(q1, q2, q3) | - deltaClosed(q1, s1, r1) and - deltaClosed(q2, s2, r2) and - deltaClosed(q3, s3, r3) and - // use noopt to force the join on `getAThreewayIntersect` to happen last. - exists(getAThreewayIntersect(s1, s2, s3)) - ) -} - -/** - * Gets a char that is matched by all the edges `s1`, `s2`, and `s3`. - * - * The result is not complete, and might miss some combination of edges that share some character. - */ -pragma[noinline] -string getAThreewayIntersect(InputSymbol s1, InputSymbol s2, InputSymbol s3) { - result = minAndMaxIntersect(s1, s2) and result = [intersect(s2, s3), intersect(s1, s3)] - or - result = minAndMaxIntersect(s1, s3) and result = [intersect(s2, s3), intersect(s1, s2)] - or - result = minAndMaxIntersect(s2, s3) and result = [intersect(s1, s2), intersect(s1, s3)] -} - -/** - * Gets the minimum and maximum characters that intersect between `a` and `b`. - * This predicate is used to limit the size of `getAThreewayIntersect`. - */ -pragma[noinline] -string minAndMaxIntersect(InputSymbol a, InputSymbol b) { - result = [min(intersect(a, b)), max(intersect(a, b))] -} - -private newtype TTrace = - Nil() or - Step(InputSymbol s1, InputSymbol s2, InputSymbol s3, TTrace t) { - isReachableFromStartTuple(_, _, t, s1, s2, s3, _, _) - } - -/** - * A list of tuples of input symbols that describe a path in the product automaton - * starting from some start state. - */ -class Trace extends TTrace { - /** - * Gets a string representation of this Trace that can be used for debug purposes. - */ - string toString() { - this = Nil() and result = "Nil()" - or - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace t | this = Step(s1, s2, s3, t) | - result = "Step(" + s1 + ", " + s2 + ", " + s3 + ", " + t + ")" - ) - } -} - -/** - * Holds if there exists a transition from `r` to `q` in the product automaton. - * Notice that the arguments are flipped, and thus the direction is backwards. - */ -pragma[noinline] -predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { step(r, _, _, _, q) } - -/** - * Holds if `tuple` is an end state in our search. - * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. - */ -predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } - -/** - * Gets the minimum length of a path from `r` to some an end state `end`. - * - * The implementation searches backwards from the end-tuple. - * This approach was chosen because it is way more efficient if the first predicate given to `shortestDistances` is small. - * The `end` argument must always be an end state. - */ -int distBackFromEnd(StateTuple r, StateTuple end) = - shortestDistances(isEndTuple/1, tupleDeltaBackwards/2)(end, r, result) - -/** - * Holds if there exists a pair of repetitions `(pivot, succ)` in the regular expression such that: - * `tuple` is reachable from `(pivot, pivot, succ)` in the product automaton, - * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, succ, succ)`, - * and a path from a start-state to `tuple` follows the transitions in `trace`. - */ -private predicate isReachableFromStartTuple( - State pivot, State succ, StateTuple tuple, Trace trace, int dist -) { - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace v | - isReachableFromStartTuple(pivot, succ, v, s1, s2, s3, tuple, dist) and - trace = Step(s1, s2, s3, v) - ) -} - -private predicate isReachableFromStartTuple( - State pivot, State succ, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, - StateTuple tuple, int dist -) { - // base case. - exists(State q1, State q2, State q3 | - isStartLoops(pivot, succ) and - step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and - tuple = MkStateTuple(q1, q2, q3) and - trace = Nil() and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) - ) - or - // recursive case - exists(StateTuple p | - isReachableFromStartTuple(pivot, succ, p, trace, dist + 1) and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) and - step(p, s1, s2, s3, tuple) - ) -} - -/** - * Gets the tuple `(pivot, succ, succ)` from the product automaton. - */ -StateTuple getAnEndTuple(State pivot, State succ) { - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, succ) -} - -/** An implementation of a chain containing chars for use by `Concretizer`. */ -private module CharTreeImpl implements CharTree { - class CharNode = Trace; - - CharNode getPrev(CharNode t) { t = Step(_, _, _, result) } - - /** Holds if `n` is used in `isPumpable`. */ - predicate isARelevantEnd(CharNode n) { - exists(State pivot, State succ | - isReachableFromStartTuple(pivot, succ, getAnEndTuple(pivot, succ), n, _) - ) - } - - string getChar(CharNode t) { - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3 | t = Step(s1, s2, s3, _) | - result = getAThreewayIntersect(s1, s2, s3) - ) - } -} - -/** - * Holds if matching repetitions of `pump` can: - * 1) Transition from `pivot` back to `pivot`. - * 2) Transition from `pivot` to `succ`. - * 3) Transition from `succ` to `succ`. - * - * From theorem 3 in the paper linked in the top of this file we can therefore conclude that - * the regular expression has polynomial backtracking - if a rejecting suffix exists. - * - * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are - * available in the `hasReDoSResult` predicate. - */ -predicate isPumpable(State pivot, State succ, string pump) { - exists(StateTuple q, Trace t | - isReachableFromStartTuple(pivot, succ, q, t, _) and - q = getAnEndTuple(pivot, succ) and - pump = Concretizer::concretize(t) - ) -} - -/** - * Holds if states starting in `state` can have polynomial backtracking with the string `pump`. - */ -predicate isReDoSCandidate(State state, string pump) { isPumpable(_, state, pump) } - -/** - * Holds if repetitions of `pump` at `t` will cause polynomial backtracking. - */ -predicate polynomialReDoS(RegExpTerm t, string pump, string prefixMsg, RegExpTerm prev) { - exists(State s, State pivot | - ReDoSPruning::hasReDoSResult(t, pump, s, prefixMsg) and - isPumpable(pivot, s, _) and - prev = pivot.getRepr() - ) -} - -/** - * Gets a message for why `term` can cause polynomial backtracking. - */ -string getReasonString(RegExpTerm term, string pump, string prefixMsg, RegExpTerm prev) { - polynomialReDoS(term, pump, prefixMsg, prev) and - result = - "Strings " + prefixMsg + "with many repetitions of '" + pump + - "' can start matching anywhere after the start of the preceeding " + prev -} - -/** - * A term that may cause a regular expression engine to perform a - * polynomial number of match attempts, relative to the input length. - */ -class PolynomialBackTrackingTerm extends InfiniteRepetitionQuantifier { - string reason; - string pump; - string prefixMsg; - RegExpTerm prev; - - PolynomialBackTrackingTerm() { - reason = getReasonString(this, pump, prefixMsg, prev) and - // there might be many reasons for this term to have polynomial backtracking - we pick the shortest one. - reason = min(string msg | msg = getReasonString(this, _, _, _) | msg order by msg.length(), msg) - } - - /** - * Holds if all non-empty successors to the polynomial backtracking term matches the end of the line. - */ - predicate isAtEndLine() { - forall(RegExpTerm succ | this.getSuccessor+() = succ and not matchesEpsilon(succ) | - succ instanceof RegExpDollar - ) - } - - /** - * Gets the string that should be repeated to cause this regular expression to perform polynomially. - */ - string getPumpString() { result = pump } - - /** - * Gets a message for which prefix a matching string must start with for this term to cause polynomial backtracking. - */ - string getPrefixMessage() { result = prefixMsg } - - /** - * Gets a predecessor to `this`, which also loops on the pump string, and thereby causes polynomial backtracking. - */ - RegExpTerm getPreviousLoop() { result = prev } - - /** - * Gets the reason for the number of match attempts. - */ - string getReason() { result = reason } -} +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +// SuperlinearBackTracking should be used directly from the shared pack, and not from this file. +deprecated private import codeql.regex.nfa.SuperlinearBackTracking::Make as Dep +import Dep diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index c18b32751ed..44e17f5588a 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -129,6 +129,42 @@ class AndroidApplicationXmlElement extends XmlElement { */ class AndroidActivityXmlElement extends AndroidComponentXmlElement { AndroidActivityXmlElement() { this.getName() = "activity" } + + /** + * Gets an `` element aliasing the activity. + */ + AndroidActivityAliasXmlElement getAnAlias() { + exists(AndroidActivityAliasXmlElement alias | this = alias.getTarget() | result = alias) + } +} + +/** + * An `` element in an Android manifest file. + */ +class AndroidActivityAliasXmlElement extends AndroidComponentXmlElement { + AndroidActivityAliasXmlElement() { this.getName() = "activity-alias" } + + /** + * Get and resolve the name of the target activity from the `android:targetActivity` attribute. + */ + string getResolvedTargetActivityName() { + exists(AndroidXmlAttribute attr | + attr = this.getAnAttribute() and attr.getName() = "targetActivity" + | + result = this.getResolvedIdentifier(attr) + ) + } + + /** + * Gets the `` element referenced by the `android:targetActivity` attribute. + */ + AndroidActivityXmlElement getTarget() { + exists(AndroidActivityXmlElement activity | + activity.getResolvedComponentName() = this.getResolvedTargetActivityName() + | + result = activity + ) + } } /** @@ -212,6 +248,13 @@ class AndroidPermissionXmlAttribute extends XmlAttribute { predicate isWrite() { this.getName() = "writePermission" } } +/** + * The attribute `android:name` or `android:targetActivity`. + */ +class AndroidIdentifierXmlAttribute extends AndroidXmlAttribute { + AndroidIdentifierXmlAttribute() { this.getName() = ["name", "targetActivity"] } +} + /** * The ` element of a `` in an Android manifest file. */ @@ -228,7 +271,7 @@ class AndroidPathPermissionXmlElement extends XmlElement { class AndroidComponentXmlElement extends XmlElement { AndroidComponentXmlElement() { this.getParent() instanceof AndroidApplicationXmlElement and - this.getName().regexpMatch("(activity|service|receiver|provider)") + this.getName().regexpMatch("(activity|activity-alias|service|receiver|provider)") } /** @@ -254,19 +297,30 @@ class AndroidComponentXmlElement extends XmlElement { ) } + /** + * Gets the value of an identifier attribute, and tries to resolve it into a fully qualified identifier. + */ + string getResolvedIdentifier(AndroidIdentifierXmlAttribute identifier) { + exists(string name | name = identifier.getValue() | + if name.matches(".%") + then + result = + this.getParent() + .(XmlElement) + .getParent() + .(AndroidManifestXmlElement) + .getPackageAttributeValue() + name + else result = name + ) + } + /** * Gets the resolved value of the `android:name` attribute of this component element. */ string getResolvedComponentName() { - if this.getComponentName().matches(".%") - then - result = - this.getParent() - .(XmlElement) - .getParent() - .(AndroidManifestXmlElement) - .getPackageAttributeValue() + this.getComponentName() - else result = this.getComponentName() + exists(AndroidXmlAttribute attr | attr = this.getAnAttribute() and attr.getName() = "name" | + result = this.getResolvedIdentifier(attr) + ) } /** diff --git a/java/ql/lib/semmle/code/xml/MavenPom.qll b/java/ql/lib/semmle/code/xml/MavenPom.qll index 8af6e6f0128..612c1468259 100644 --- a/java/ql/lib/semmle/code/xml/MavenPom.qll +++ b/java/ql/lib/semmle/code/xml/MavenPom.qll @@ -381,6 +381,15 @@ class DeclaredRepository extends PomElement { * be the string contents of that tag. */ string getRepositoryUrl() { result = this.getAChild("url").(PomElement).getValue() } + + /** + * Holds if this repository is disabled in both the `releases` and `snapshots` policies. + */ + predicate isDisabled() { + forex(PomElement policy | policy = this.getAChild(["releases", "snapshots"]) | + policy.getAChild("enabled").(PomElement).getValue() = "false" + ) + } } /** diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme new file mode 100644 index 00000000000..709f1d1fd04 --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/old.dbscheme @@ -0,0 +1,1240 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme new file mode 100644 index 00000000000..44d61b266be --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/semmlecode.dbscheme @@ -0,0 +1,1246 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @class ref +) diff --git a/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties new file mode 100644 index 00000000000..1c05ac39dbe --- /dev/null +++ b/java/ql/lib/upgrades/709f1d1fd04ffd9bbcf242f17b120f8a389949bd/upgrade.properties @@ -0,0 +1,2 @@ +description: Add compilation_info +compatibility: backwards diff --git a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql index 83093433123..6942eaab69a 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql @@ -14,5 +14,6 @@ from RefType t where t.fromSource() and not t instanceof AnonymousClass and + not t.isCompilerGenerated() and not t.getName().substring(0, 1).toUpperCase() = t.getName().substring(0, 1) select t, "Class and interface names should start in uppercase." diff --git a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql index 99ab9003e60..b4133761e27 100644 --- a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql +++ b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql @@ -37,6 +37,7 @@ predicate oneLineStatement(Stmt s, File f, int line, int col) { from Stmt s, Stmt s2 where exists(File f, int line, int col, int col2 | + f.isJavaSourceFile() and oneLineStatement(s, f, line, col) and oneLineStatement(s2, f, line, col2) and col < col2 and diff --git a/java/ql/src/AlertSuppression.ql b/java/ql/src/AlertSuppression.ql index 3fbecf8cfc1..d37bd174692 100644 --- a/java/ql/src/AlertSuppression.ql +++ b/java/ql/src/AlertSuppression.ql @@ -53,9 +53,7 @@ class SuppressionComment extends Javadoc { /** * The scope of an alert suppression comment. */ -class SuppressionScope extends @javadoc { - SuppressionScope() { this instanceof SuppressionComment } - +class SuppressionScope extends @javadoc instanceof SuppressionComment { /** Gets a suppression comment with this scope. */ SuppressionComment getSuppressionComment() { result = this } @@ -69,7 +67,7 @@ class SuppressionScope extends @javadoc { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) + super.covers(filepath, startline, startcolumn, endline, endcolumn) } /** Gets a textual representation of this element. */ diff --git a/java/ql/src/AlertSuppressionAnnotations.ql b/java/ql/src/AlertSuppressionAnnotations.ql index 7f0ee74a0d8..91cb65934cd 100644 --- a/java/ql/src/AlertSuppressionAnnotations.ql +++ b/java/ql/src/AlertSuppressionAnnotations.ql @@ -69,9 +69,7 @@ class SuppressionAnnotation extends SuppressWarningsAnnotation { /** * The scope of an alert suppression annotation. */ -class SuppressionScope extends @annotation { - SuppressionScope() { this instanceof SuppressionAnnotation } - +class SuppressionScope extends @annotation instanceof SuppressionAnnotation { /** Gets a suppression annotation with this scope. */ SuppressionAnnotation getSuppressionAnnotation() { result = this } @@ -85,7 +83,7 @@ class SuppressionScope extends @annotation { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.(SuppressionAnnotation).covers(filepath, startline, startcolumn, endline, endcolumn) + super.covers(filepath, startline, startcolumn, endline, endcolumn) } /** Gets a textual representation of this element. */ diff --git a/java/ql/src/Architecture/Dependencies/MutualDependency.ql b/java/ql/src/Architecture/Dependencies/MutualDependency.ql index c6ef88cd305..6d66daf1c67 100644 --- a/java/ql/src/Architecture/Dependencies/MutualDependency.ql +++ b/java/ql/src/Architecture/Dependencies/MutualDependency.ql @@ -30,6 +30,8 @@ where t2.getName().toLowerCase().matches("%visitor%") or t1.getAMethod().getName().toLowerCase().matches("%visit%") or t2.getAMethod().getName().toLowerCase().matches("%visit%") or - t1.getPackage() = t2.getPackage() + t1.getPackage() = t2.getPackage() or + t1.getFile().isKotlinSourceFile() or + t2.getFile().isKotlinSourceFile() ) select t1, "This type and type $@ are mutually dependent.", t2, t2.getName() diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 61b4170ca74..7bab127cafc 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.4.6 + +### Minor Analysis Improvements + +* Kotlin extraction will now fail if the Kotlin version in use is at least 1.7.30. This is to ensure using an as-yet-unsupported version is noticable, rather than silently failing to extract Kotlin code and therefore producing false-negative results. + +## 0.4.5 + +No user-facing changes. + +## 0.4.4 + +### New Queries + +* The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the Android keyboard cache. + ## 0.4.3 No user-facing changes. diff --git a/java/ql/src/DeadCode/DeadClass.ql b/java/ql/src/DeadCode/DeadClass.ql index 8a1b5e0be77..23f08fec3b8 100644 --- a/java/ql/src/DeadCode/DeadClass.ql +++ b/java/ql/src/DeadCode/DeadClass.ql @@ -14,6 +14,8 @@ import semmle.code.java.deadcode.DeadCode from DeadClass c, Element origin, string reason where + not c.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and if exists(DeadRoot root | root = c.getADeadRoot() | not root = c.getACallable()) then ( // Report a list of the dead roots. diff --git a/java/ql/src/DeadCode/DeadField.ql b/java/ql/src/DeadCode/DeadField.ql index 6a80e13e716..7a8bca7ac7b 100644 --- a/java/ql/src/DeadCode/DeadField.ql +++ b/java/ql/src/DeadCode/DeadField.ql @@ -15,6 +15,8 @@ import semmle.code.java.deadcode.DeadCode from DeadField f, Element origin, string reason where + not f.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and not f.isInDeadScope() and if f.getAnAccess() instanceof FieldRead then ( diff --git a/java/ql/src/DeadCode/DeadMethod.ql b/java/ql/src/DeadCode/DeadMethod.ql index 8b5d0f155ef..77401341b6c 100644 --- a/java/ql/src/DeadCode/DeadMethod.ql +++ b/java/ql/src/DeadCode/DeadMethod.ql @@ -15,6 +15,8 @@ import semmle.code.java.deadcode.DeadCode from DeadMethod c, Callable origin, string reason where + not c.getFile().isKotlinSourceFile() and + not origin.getFile().isKotlinSourceFile() and not c.isInDeadScope() and if exists(DeadRoot deadRoot | deadRoot = getADeadRoot(c) | deadRoot.getSourceDeclaration() != c) then ( diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index 1f05298878a..1c7bb13c065 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -64,6 +64,7 @@ class UnimplementedEquals extends EqualsMethod { from EqualsMethod m where + m.getFile().isJavaSourceFile() and exists(m.getBody()) and exists(Parameter p | p = m.getAParameter() | // The parameter has no type test diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index a8faf679f7e..92da62633d8 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -33,6 +33,7 @@ predicate safeReaderType(RefType t) { from ClassInstanceExpr cie, RefType t where + cie.getFile().isJavaSourceFile() and badCloseableInit(cie) and cie.getType() = t and readerType(t) and diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql index 44e77f3fe8f..e7584aba67d 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql @@ -15,6 +15,7 @@ import CloseType from CloseableInitExpr cie, RefType t where + cie.getFile().isJavaSourceFile() and badCloseableInit(cie) and cie.getType() = t and sqlType(t) and diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql index 0143a946133..fa04de220bf 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql @@ -29,6 +29,7 @@ predicate safeWriterType(RefType t) { from ClassInstanceExpr cie, RefType t where + cie.getFile().isJavaSourceFile() and badCloseableInit(cie) and cie.getType() = t and writerType(t) and diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql index 920958ce3ce..a39e29f6576 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql @@ -55,6 +55,8 @@ string nonSerialReason(RefType t) { predicate exceptions(Class c, Field f) { f.getDeclaringType() = c and ( + c.isCompilerGenerated() + or // `Serializable` objects with custom `readObject` or `writeObject` methods // may write out the "non-serializable" fields in a different way. c.declaresMethod("readObject") diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql index 1bf54abb89f..8081c551eed 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql @@ -77,7 +77,7 @@ predicate exceptions(NestedClass inner) { from NestedClass inner, Class outer, string advice where - inner.fromSource() and + inner.getFile().isJavaSourceFile() and isSerializable(inner) and outer = enclosingInstanceType+(inner) and not isSerializable(outer) and diff --git a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql index 4dd2c397a87..411890474e5 100644 --- a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql +++ b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql @@ -56,6 +56,7 @@ predicate blockParent(Stmt empty, string msg) { from Stmt empty, string msg where + empty.getFile().isJavaSourceFile() and empty = emptyBody() and blockParent(empty, msg) select empty, msg + " Typographical error or missing code?" diff --git a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql index 3355fd22190..c50a9a5f1a4 100644 --- a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql +++ b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql @@ -75,6 +75,7 @@ predicate isMustBeQualifierMockingMethod(Method m) { predicate relevantMethodCall(MethodAccess ma, Method m) { // For "return value ignored", all method calls are relevant. + not ma.getFile().isKotlinSourceFile() and ma.getMethod() = m and not m.getReturnType().hasName("void") and (not isMockingMethod(m) or isMustBeQualifierMockingMethod(m)) and diff --git a/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverage.ql b/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverage.ql new file mode 100644 index 00000000000..eb03a785702 --- /dev/null +++ b/java/ql/src/Metrics/Summaries/GeneratedVsManualCoverage.ql @@ -0,0 +1,76 @@ +/** + * @id java/summary/generated-vs-manual-coverage + * @name Metrics of generated versus manual MaD coverage + * @description Expose metrics for the number of API endpoints covered by generated versus manual MaD models. + * @kind table + * @tags summary + */ + +import java +import semmle.code.java.dataflow.FlowSummary +import utils.modelgenerator.internal.CaptureModels + +/** + * Returns the number of `DataFlowTargetApi`s with Summary MaD models + * for a given package and provenance. + */ +bindingset[package] +private int getNumMadModeledApis(string package, string provenance) { + provenance in ["generated", "manual", "both"] and + result = + count(SummarizedCallable sc | + package = sc.asCallable().getCompilationUnit().getPackage().getName() and + sc.asCallable() instanceof DataFlowTargetApi and + ( + // "auto-only" + sc.isAutoGenerated() and + provenance = "generated" + or + // "manual-only" + sc.hasProvenance(false) and + not sc.hasProvenance(true) and + provenance = "manual" + or + // "both" + sc.hasProvenance(false) and + sc.hasProvenance(true) and + provenance = "both" + ) + ) +} + +/** Returns the total number of `DataFlowTargetApi`s for a given package. */ +private int getNumApis(string package) { + result = + strictcount(DataFlowTargetApi dataFlowTargApi | + package = dataFlowTargApi.getCompilationUnit().getPackage().getName() + ) +} + +from + string package, int generatedOnly, int both, int manualOnly, int generated, int manual, int non, + int all, float coverage, float generatedCoverage, float manualCoverage, + float manualCoveredByGenerated, float generatedCoveredByManual, float match +where + // count the number of APIs with generated-only, both, and manual-only MaD models for each package + generatedOnly = getNumMadModeledApis(package, "generated") and + both = getNumMadModeledApis(package, "both") and + manualOnly = getNumMadModeledApis(package, "manual") and + // calculate the total generated and total manual numbers + generated = generatedOnly + both and + manual = manualOnly + both and + // count the total number of `DataFlowTargetApi`s for each package + all = getNumApis(package) and + non = all - (generatedOnly + both + manualOnly) and + // Proportion of coverage + coverage = (generatedOnly + both + manualOnly).(float) / all and + generatedCoverage = generated.(float) / all and + manualCoverage = manual.(float) / all and + // Proportion of manual models covered by generated ones + manualCoveredByGenerated = both.(float) / (both + manualOnly) and + // Proportion of generated models covered by manual ones + generatedCoveredByManual = both.(float) / (both + generatedOnly) and + // Proportion of data points that match + match = (both.(float) + non) / all +select package, generatedOnly, both, manualOnly, non, all, coverage, generatedCoverage, + manualCoverage, manualCoveredByGenerated, generatedCoveredByManual, match order by package diff --git a/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql b/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql index d054659892c..b8ea3e52dbd 100644 --- a/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql +++ b/java/ql/src/Security/CWE/CWE-020/OverlyLargeRange.ql @@ -12,14 +12,15 @@ * external/cwe/cwe-020 */ -import semmle.code.java.security.OverlyLargeRangeQuery +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.OverlyLargeRangeQuery::Make -RegExpCharacterClass potentialMisparsedCharClass() { +TreeView::RegExpCharacterClass potentialMisparsedCharClass() { // nested char classes are currently misparsed - result.getAChild().(RegExpNormalChar).getValue() = "[" + result.getAChild().(TreeView::RegExpNormalChar).getValue() = "[" } -from RegExpCharacterRange range, string reason +from TreeView::RegExpCharacterRange range, string reason where problem(range, reason) and not range.getParent() = potentialMisparsedCharClass() diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java index 9246a19dc8d..339640ccc32 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java @@ -16,9 +16,9 @@ public void sendUserFileFixed(Socket sock, String user) { // ... // GOOD: remove all dots and directory delimiters from the filename before using - String filename = filenameReader.readLine().replaceAll("\.", "").replaceAll("/", ""); + String filename = filenameReader.readLine().replaceAll("\\.", "").replaceAll("/", ""); BufferedReader fileReader = new BufferedReader( new FileReader("/home/" + user + "/" + filename)); // ... -} \ No newline at end of file +} diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.qhelp b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.qhelp new file mode 100644 index 00000000000..a60ec36995b --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.qhelp @@ -0,0 +1,49 @@ + + + +

+ Enabling JavaScript in an Android WebView allows the execution of + JavaScript code in the context of the running application. This creates a + cross-site scripting vulnerability. +

+ +

+ For example, if your application's WebView allows for visiting web pages + that you do not trust, it is possible for an attacker to lead the user to + a page which loads malicious JavaScript. +

+ +

+ You can enable or disable Javascript execution using + the setJavaScriptEnabled method of the settings of a WebView. +

+
+ + +

JavaScript execution is disabled by default. You can explicitly disable + it by calling setJavaScriptEnabled(false) on the settings of + the WebView.

+ +

If JavaScript is necessary, only load content from trusted servers using encrypted channels, such as HTTPS with certificate verification.

+
+ + +

In the following (bad) example, a WebView has JavaScript enabled in its settings:

+ + + +

In the following (good) example, a WebView explicitly disallows JavaScript execution:

+ + + +
+ + +
  • + Android documentation: setJavaScriptEnabled +
  • +
    + +
    diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql new file mode 100644 index 00000000000..d0a92925934 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql @@ -0,0 +1,20 @@ +/** + * @name Android WebView JavaScript settings + * @description Enabling JavaScript execution in a WebView can result in cross-site scripting attacks. + * @kind problem + * @id java/android-websettings-javascript-enabled + * @problem.severity warning + * @security-severity 6.1 + * @precision medium + * @tags security + * external/cwe/cwe-079 + */ + +import java +import semmle.code.java.frameworks.android.WebView + +from MethodAccess ma +where + ma.getMethod() instanceof AllowJavaScriptMethod and + ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true +select ma, "JavaScript execution enabled in WebView." diff --git a/java/ql/src/Security/CWE/CWE-079/WebSettingsDisableJavascript.java b/java/ql/src/Security/CWE/CWE-079/WebSettingsDisableJavascript.java new file mode 100644 index 00000000000..43a8cd92c0e --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/WebSettingsDisableJavascript.java @@ -0,0 +1,2 @@ +WebSettings settings = webview.getSettings(); +settings.setJavaScriptEnabled(false); diff --git a/java/ql/src/Security/CWE/CWE-079/WebSettingsEnableJavascript.java b/java/ql/src/Security/CWE/CWE-079/WebSettingsEnableJavascript.java new file mode 100644 index 00000000000..adfac156009 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-079/WebSettingsEnableJavascript.java @@ -0,0 +1,2 @@ +WebSettings settings = webview.getSettings(); +settings.setJavaScriptEnabled(true); diff --git a/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql b/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql index 259f36fb42b..bce8d934ac6 100644 --- a/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql +++ b/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql @@ -20,9 +20,7 @@ int leftWidth(ComparisonExpr e) { result = e.getLeftOperand().getType().(NumType int rightWidth(ComparisonExpr e) { result = e.getRightOperand().getType().(NumType).getWidthRank() } -abstract class WideningComparison extends BinaryExpr { - WideningComparison() { this instanceof ComparisonExpr } - +abstract class WideningComparison extends BinaryExpr instanceof ComparisonExpr { abstract Expr getNarrower(); abstract Expr getWider(); diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.qhelp b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.qhelp new file mode 100644 index 00000000000..44d69f410fb --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.qhelp @@ -0,0 +1,65 @@ + + + +

    + Allowing file access in an Android WebView can expose a device's file system to + the JavaScript running in that WebView. If the JavaScript contains + vulnerabilities or the WebView loads untrusted content, file access + allows an attacker to steal the user's data. +

    +
    + + +

    When possible, do not allow file access. The file access settings + are disabled by default. You can explicitly disable file access by setting the + following settings to false:

    + +
      +
    • setAllowFileAccess
    • +
    • setAllowFileAccessFromFileURLs
    • +
    • setAllowUniversalAccessFromFileURLs
    • +
    + +

    If your application requires access to the file system, it is best to + avoid using file:// URLs. Instead, use an alternative that + loads files via HTTPS, such + as androidx.webkit.WebViewAssetLoader.

    +
    + + +

    In the following (bad) example, the WebView is configured with settings + that allow local file access.

    + + + +

    In the following (good) example, the WebView is configured to disallow file access.

    + + + +

    + As mentioned previously, asset loaders can load files without file system + access. In the following (good) example, an asset loader is configured to + load assets over HTTPS. +

    + + +
    + + +
  • + Android documentation: WebSettings.setAllowFileAccess. +
  • +
  • + Android documentation: WebSettings.setAllowFileAccessFromFileURLs. +
  • +
  • + Android documentation: WebSettings.setAllowUniversalAccessFromFileURLs. +
  • +
  • + Android documentation: WebViewAssetLoader. +
  • +
    + +
    diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql new file mode 100644 index 00000000000..a477fbe9e82 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql @@ -0,0 +1,22 @@ +/** + * @name Android WebSettings file access + * @kind problem + * @description Enabling access to the file system in a WebView allows attackers to view sensitive information. + * @id java/android-websettings-file-access + * @problem.severity warning + * @security-severity 6.5 + * @precision medium + * @tags security + * external/cwe/cwe-200 + */ + +import java +import semmle.code.java.frameworks.android.WebView + +from MethodAccess ma +where + ma.getMethod() instanceof CrossOriginAccessMethod and + ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true +select ma, + "WebView setting " + ma.getMethod().getName() + + " may allow for unauthorized access of sensitive information." diff --git a/java/ql/src/Security/CWE/CWE-200/AssetLoaderExample.java b/java/ql/src/Security/CWE/CWE-200/AssetLoaderExample.java new file mode 100644 index 00000000000..dfd5afda5ae --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/AssetLoaderExample.java @@ -0,0 +1,15 @@ +WebViewAssetLoader loader = new WebViewAssetLoader.Builder() + // Replace the domain with a domain you control, or use the default + // appassets.androidplatform.com + .setDomain("appassets.example.com") + .addPathHandler("/resources", new AssetsPathHandler(this)) + .build(); + +webView.setWebViewClient(new WebViewClientCompat() { + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + return assetLoader.shouldInterceptRequest(request.getUrl()); + } +}); + +webView.loadUrl("https://appassets.example.com/resources/www/index.html"); diff --git a/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessSafe.java b/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessSafe.java new file mode 100644 index 00000000000..6002888cba1 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessSafe.java @@ -0,0 +1,5 @@ +WebSettings settings = view.getSettings(); + +settings.setAllowFileAccess(false); +settings.setAllowFileAccessFromURLs(false); +settings.setAllowUniversalAccessFromURLs(false); diff --git a/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessUnsafe.java b/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessUnsafe.java new file mode 100644 index 00000000000..6c17d66c3b0 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-200/WebViewFileAccessUnsafe.java @@ -0,0 +1,5 @@ +WebSettings settings = view.getSettings(); + +settings.setAllowFileAccess(true); +settings.setAllowFileAccessFromURLs(true); +settings.setAllowUniversalAccessFromURLs(true); diff --git a/java/ql/src/Security/CWE/CWE-524/Example.xml b/java/ql/src/Security/CWE/CWE-524/Example.xml new file mode 100644 index 00000000000..7317eda1618 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-524/Example.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp new file mode 100644 index 00000000000..7a16bbd6f80 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.qhelp @@ -0,0 +1,33 @@ + + + + +

    When a user enters information in a text input field on an Android application, their input is saved to a keyboard cache which provides autocomplete suggestions and predictions. There is a risk that sensitive user data, such as passwords or banking information, may be leaked to other applications via the keyboard cache.

    + +
    + + +

    For input fields expected to accept sensitive information, use input types such as "textNoSuggestions" (or "textPassword" for a password) to ensure the input does not get stored in the keyboard cache.

    +

    Optionally, instead of declaring an input type through XML, you can set the input type in your code using TextView.setInputType().

    +
    + + +

    In the following example, the field labeled BAD allows the password to be saved to the keyboard cache, + whereas the field labeled GOOD uses the "textPassword" input type to ensure the password is not cached.

    + + + +
    + + +
  • + OWASP Mobile Application Security Testing Guide: Determining Whether the Keyboard Cache Is Disabled for Text Input Fields. +
  • +
  • + Android Developers: android:inputType attribute documentation. +
  • + +
    +
    diff --git a/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql new file mode 100644 index 00000000000..d5a7bc50c05 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-524/SensitiveKeyboardCache.ql @@ -0,0 +1,18 @@ +/** + * @name Android sensitive keyboard cache + * @description Allowing the keyboard to cache sensitive information may result in information leaks to other applications. + * @kind problem + * @problem.severity warning + * @security-severity 8.1 + * @id java/android/sensitive-keyboard-cache + * @tags security + * external/cwe/cwe-524 + * @precision medium + */ + +import java +import semmle.code.java.security.SensitiveKeyboardCacheQuery + +from AndroidEditableXmlElement el +where el = getASensitiveCachedInput() +select el, "This input field may contain sensitive information that is saved to the keyboard cache." diff --git a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql index de4a3bd8ffe..0766ee07134 100644 --- a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql +++ b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql @@ -26,18 +26,31 @@ predicate isSafeSecureCookieSetting(Expr e) { ) } +class SecureCookieConfiguration extends DataFlow::Configuration { + SecureCookieConfiguration() { this = "SecureCookieConfiguration" } + + override predicate isSource(DataFlow::Node source) { + exists(MethodAccess ma, Method m | ma.getMethod() = m | + m.getDeclaringType() instanceof TypeCookie and + m.getName() = "setSecure" and + source.asExpr() = ma.getQualifier() and + forex(DataFlow::Node argSource | + DataFlow::localFlow(argSource, DataFlow::exprNode(ma.getArgument(0))) and + not DataFlow::localFlowStep(_, argSource) + | + isSafeSecureCookieSetting(argSource.asExpr()) + ) + ) + } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = + any(MethodAccess add | add.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) + } +} + from MethodAccess add where add.getMethod() instanceof ResponseAddCookieMethod and - not exists(Variable cookie, MethodAccess m | - add.getArgument(0) = cookie.getAnAccess() and - m.getMethod().getName() = "setSecure" and - forex(DataFlow::Node argSource | - DataFlow::localFlow(argSource, DataFlow::exprNode(m.getArgument(0))) and - not DataFlow::localFlowStep(_, argSource) - | - isSafeSecureCookieSetting(argSource.asExpr()) - ) and - m.getQualifier() = cookie.getAnAccess() - ) + not any(SecureCookieConfiguration df).hasFlowToExpr(add.getArgument(0)) select add, "Cookie is added to response without the 'secure' flag being set." diff --git a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql index 75cd8335fac..a84f1c5213e 100644 --- a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql +++ b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql @@ -17,7 +17,9 @@ import java import semmle.code.java.security.regexp.PolynomialReDoSQuery import DataFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp +from + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp where hasPolynomialReDoSResult(source, sink, regexp) select sink, source, sink, "This $@ that depends on a $@ may run slow on strings " + regexp.getPrefixMessage() + diff --git a/java/ql/src/Security/CWE/CWE-730/ReDoS.ql b/java/ql/src/Security/CWE/CWE-730/ReDoS.ql index 23e258e8915..ca4750fc858 100644 --- a/java/ql/src/Security/CWE/CWE-730/ReDoS.ql +++ b/java/ql/src/Security/CWE/CWE-730/ReDoS.ql @@ -14,12 +14,12 @@ * external/cwe/cwe-400 */ -import java -import semmle.code.java.security.regexp.ExponentialBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.ExponentialBackTracking::Make as ExponentialBackTracking -from RegExpTerm t, string pump, State s, string prefixMsg +from TreeView::RegExpTerm t, string pump, ExponentialBackTracking::State s, string prefixMsg where - hasReDoSResult(t, pump, s, prefixMsg) and + ExponentialBackTracking::hasReDoSResult(t, pump, s, prefixMsg) and // exclude verbose mode regexes for now not t.getRegex().getAMode() = "VERBOSE" select t, diff --git a/java/ql/src/Security/CWE/CWE-730/RegexInjection.java b/java/ql/src/Security/CWE/CWE-730/RegexInjection.java new file mode 100644 index 00000000000..673d5a2fa40 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.java @@ -0,0 +1,22 @@ +import java.util.regex.Pattern; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; + +public class RegexInjectionDemo extends HttpServlet { + + public boolean badExample(javax.servlet.http.HttpServletRequest request) { + String regex = request.getParameter("regex"); + String input = request.getParameter("input"); + + // BAD: Unsanitized user input is used to construct a regular expression + return input.matches(regex); + } + + public boolean goodExample(javax.servlet.http.HttpServletRequest request) { + String regex = request.getParameter("regex"); + String input = request.getParameter("input"); + + // GOOD: User input is sanitized before constructing the regex + return input.matches(Pattern.quote(regex)); + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.qhelp b/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp similarity index 67% rename from java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.qhelp rename to java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp index 6cd80b52f75..3e239d07107 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.qhelp @@ -15,25 +15,25 @@ perform a Denial of Service attack.

    Before embedding user input into a regular expression, use a sanitization function -to escape meta-characters that have special meaning. +such as Pattern.quote to escape meta-characters that have special meaning.

    -The following example shows a HTTP request parameter that is used to construct a regular expression: +The following example shows an HTTP request parameter that is used to construct a regular expression.

    -

    In the first case the user-provided regex is not escaped. -If a malicious user provides a regex that has exponential worst case performance, +If a malicious user provides a regex whose worst-case performance is exponential, then this could lead to a Denial of Service.

    -In the second case, the user input is escaped using escapeSpecialRegexChars before being included +In the second case, the user input is escaped using Pattern.quote before being included in the regular expression. This ensures that the user cannot insert characters which have a special meaning in regular expressions.

    +
    @@ -44,5 +44,8 @@ OWASP:
  • Wikipedia: ReDoS.
  • +
  • +Java API Specification: Pattern.quote. +
  • diff --git a/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql new file mode 100644 index 00000000000..820e0949d22 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql @@ -0,0 +1,23 @@ +/** + * @name Regular expression injection + * @description User input should not be used in regular expressions without first being escaped, + * otherwise a malicious user may be able to provide a regex that could require + * exponential time on certain inputs. + * @kind path-problem + * @problem.severity error + * @security-severity 7.5 + * @precision high + * @id java/regex-injection + * @tags security + * external/cwe/cwe-730 + * external/cwe/cwe-400 + */ + +import java +import semmle.code.java.security.regexp.RegexInjectionQuery +import DataFlow::PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", + source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql b/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql index ede03c50b00..dca1a9cc4b7 100644 --- a/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql +++ b/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql @@ -17,7 +17,8 @@ import java import semmle.code.xml.MavenPom predicate isInsecureRepositoryUsage(DeclaredRepository repository) { - repository.getRepositoryUrl().regexpMatch("(?i)^(http|ftp)://(?!localhost[:/]).*") + repository.getRepositoryUrl().regexpMatch("(?i)^(http|ftp)://(?!localhost[:/]).*") and + not repository.isDisabled() } from DeclaredRepository repository diff --git a/java/ql/src/Telemetry/ExternalApi.qll b/java/ql/src/Telemetry/ExternalApi.qll index c3e11d4b9bc..2f7ebcc9d19 100644 --- a/java/ql/src/Telemetry/ExternalApi.qll +++ b/java/ql/src/Telemetry/ExternalApi.qll @@ -31,11 +31,17 @@ private string containerAsJar(Container container) { if container instanceof JarFile then result = container.getBaseName() else result = "rt.jar" } +/** Holds if the given callable is not worth supporting. */ +private predicate isUninteresting(Callable c) { + c.getDeclaringType() instanceof TestLibrary or + c.(Constructor).isParameterless() +} + /** * An external API from either the Standard Library or a 3rd party library. */ class ExternalApi extends Callable { - ExternalApi() { not this.fromSource() } + ExternalApi() { not this.fromSource() and not isUninteresting(this) } /** * Gets information about the external API in the form expected by the CSV modeling framework. @@ -73,18 +79,6 @@ class ExternalApi extends Callable { TaintTracking::localAdditionalTaintStep(this.getAnInput(), _) } - /** Holds if this API is a constructor without parameters. */ - private predicate isParameterlessConstructor() { - this instanceof Constructor and this.getNumberOfParameters() = 0 - } - - /** Holds if this API is part of a common testing library or framework. */ - private predicate isTestLibrary() { this.getDeclaringType() instanceof TestLibrary } - - /** Holds if this API is not worth supporting. */ - predicate isUninteresting() { this.isTestLibrary() or this.isParameterlessConstructor() } - - /** Holds if this API is a known source. */ predicate isSource() { this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) } diff --git a/java/ql/src/Telemetry/ExternalLibraryUsage.ql b/java/ql/src/Telemetry/ExternalLibraryUsage.ql index bf63b91d02a..6fe9e3e0915 100644 --- a/java/ql/src/Telemetry/ExternalLibraryUsage.ql +++ b/java/ql/src/Telemetry/ExternalLibraryUsage.ql @@ -14,8 +14,7 @@ private predicate getRelevantUsages(string jarname, int usages) { strictcount(Call c, ExternalApi a | c.getCallee().getSourceDeclaration() = a and not c.getFile() instanceof GeneratedFile and - a.jarContainer() = jarname and - not a.isUninteresting() + a.jarContainer() = jarname ) } diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 0eb420ba651..48eb49a1b07 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -9,6 +9,13 @@ import java import semmle.code.java.Diagnostics +predicate compilationInfo(string key, int value) { + exists(Compilation c, string infoKey | + key = infoKey + ": " + c.getInfo(infoKey) and + value = 1 + ) +} + predicate fileCount(string key, int value) { key = "Number of files" and value = strictcount(File f) @@ -53,13 +60,38 @@ predicate extractorDiagnostics(string key, int value) { ) } +/* + * Just counting the diagnostics doesn't give the full picture, as + * CODEQL_EXTRACTOR_KOTLIN_DIAGNOSTIC_LIMIT means that some diagnostics + * will be suppressed. In that case, we need to look for the + * suppression message, uncount those that did get emitted, uncount the + * suppression message itself, and then add on the full count. + */ + +predicate extractorTotalDiagnostics(string key, int value) { + exists(string extractor, string limitRegex | + limitRegex = "Total of ([0-9]+) diagnostics \\(reached limit of ([0-9]+)\\).*" and + key = "Total number of diagnostics from " + extractor and + value = + strictcount(Diagnostic d | d.getGeneratedBy() = extractor) + + sum(Diagnostic d | + d.getGeneratedBy() = extractor + | + d.getMessage().regexpCapture(limitRegex, 1).toInt() - + d.getMessage().regexpCapture(limitRegex, 2).toInt() - 1 + ) + ) +} + from string key, int value where + compilationInfo(key, value) or fileCount(key, value) or fileCountByExtension(key, value) or totalNumberOfLines(key, value) or numberOfLinesOfCode(key, value) or totalNumberOfLinesByExtension(key, value) or numberOfLinesOfCodeByExtension(key, value) or - extractorDiagnostics(key, value) + extractorDiagnostics(key, value) or + extractorTotalDiagnostics(key, value) select key, value diff --git a/java/ql/src/Telemetry/SupportedExternalApis.ql b/java/ql/src/Telemetry/SupportedExternalApis.ql new file mode 100644 index 00000000000..ad1554dba91 --- /dev/null +++ b/java/ql/src/Telemetry/SupportedExternalApis.ql @@ -0,0 +1,20 @@ +/** + * @name Usage of supported APIs coming from external libraries + * @description A list of supported 3rd party APIs used in the codebase. Excludes test and generated code. + * @kind metric + * @tags summary telemetry + * @id java/telemetry/supported-external-api + */ + +import java +import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +import ExternalApi + +private predicate relevant(ExternalApi api) { + api.isSupported() or + api = any(FlowSummaryImpl::Public::NeutralCallable nsc).asCallable() +} + +from string apiName, int usages +where Results::restrict(apiName, usages) +select apiName, usages order by usages desc diff --git a/java/ql/src/Telemetry/SupportedExternalSinks.ql b/java/ql/src/Telemetry/SupportedExternalSinks.ql index 7593adeed2a..6456b7e296c 100644 --- a/java/ql/src/Telemetry/SupportedExternalSinks.ql +++ b/java/ql/src/Telemetry/SupportedExternalSinks.ql @@ -9,10 +9,7 @@ import java import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.isSink() -} +private predicate relevant(ExternalApi api) { api.isSink() } from string apiName, int usages where Results::restrict(apiName, usages) diff --git a/java/ql/src/Telemetry/SupportedExternalSources.ql b/java/ql/src/Telemetry/SupportedExternalSources.ql index 89f9b37cb55..9bb0f1202c1 100644 --- a/java/ql/src/Telemetry/SupportedExternalSources.ql +++ b/java/ql/src/Telemetry/SupportedExternalSources.ql @@ -9,10 +9,7 @@ import java import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.isSource() -} +private predicate relevant(ExternalApi api) { api.isSource() } from string apiName, int usages where Results::restrict(apiName, usages) diff --git a/java/ql/src/Telemetry/SupportedExternalTaint.ql b/java/ql/src/Telemetry/SupportedExternalTaint.ql index 3f995138812..52792b2bbd2 100644 --- a/java/ql/src/Telemetry/SupportedExternalTaint.ql +++ b/java/ql/src/Telemetry/SupportedExternalTaint.ql @@ -9,10 +9,7 @@ import java import ExternalApi -private predicate relevant(ExternalApi api) { - not api.isUninteresting() and - api.hasSummary() -} +private predicate relevant(ExternalApi api) { api.hasSummary() } from string apiName, int usages where Results::restrict(apiName, usages) diff --git a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql index 16871f87a53..3031529626d 100644 --- a/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql +++ b/java/ql/src/Telemetry/UnsupportedExternalAPIs.ql @@ -8,13 +8,11 @@ import java import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -import semmle.code.java.dataflow.internal.NegativeSummary import ExternalApi private predicate relevant(ExternalApi api) { - not api.isUninteresting() and not api.isSupported() and - not api = any(FlowSummaryImpl::Public::NegativeSummarizedCallable nsc).asCallable() + not api = any(FlowSummaryImpl::Public::NeutralCallable nsc).asCallable() } from string apiName, int usages diff --git a/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql b/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql index 814a45bef6d..9b87a358905 100644 --- a/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql +++ b/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql @@ -92,13 +92,16 @@ class ComparisonOrEquality extends BinaryExpr { from Expr e, string pattern, string rewrite where - e.(BoolCompare).simplify(pattern, rewrite) - or - conditionalWithBool(e, pattern, rewrite) - or - e.(LogNotExpr).getExpr().(ComparisonOrEquality).negate(pattern, rewrite) - or - e.(LogNotExpr).getExpr() instanceof LogNotExpr and - pattern = "!!A" and - rewrite = "A" + e.getFile().isJavaSourceFile() and + ( + e.(BoolCompare).simplify(pattern, rewrite) + or + conditionalWithBool(e, pattern, rewrite) + or + e.(LogNotExpr).getExpr().(ComparisonOrEquality).negate(pattern, rewrite) + or + e.(LogNotExpr).getExpr() instanceof LogNotExpr and + pattern = "!!A" and + rewrite = "A" + ) select e, "Expressions of the form \"" + pattern + "\" can be simplified to \"" + rewrite + "\"." diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll index 82933aa9bac..8837b207e20 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll @@ -1,4 +1,4 @@ -/* +/** * Provides classes and predicates for "dead locals": which variables are used, which assignments are useless, etc. */ diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll index 11dbd5cd8d3..5fc7e9069cd 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll @@ -8,26 +8,26 @@ private predicate trivialPositiveIntValue(string s) { s = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", - "17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", - "16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127", - "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", - "4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", - "0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", - "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", - "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", - "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", - "0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007", - "0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", - "0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", - "0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", - "0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", - "0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", - "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", - "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f", - "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", - "0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", - "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000", - "10000", "100000", "1000000", "10000000", "100000000", "1000000000" + "17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", + "32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511", + "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295", + "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020", + "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", + "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", + "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", + "0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", + "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", + "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", + "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", + "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", + "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010", + "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000", + "0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", + "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x01", + "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x03", "0x07", "0x0f", "0x1f", + "0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000", + "100000000", "1000000000" ] } diff --git a/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql b/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql index b80f86cd810..c6d8d796309 100644 --- a/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql +++ b/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql @@ -72,12 +72,16 @@ predicate rebox(Assignment e, Variable v) { from Expr e, string conv where - boxed(e) and conv = "This expression is implicitly boxed." - or - unboxed(e) and conv = "This expression is implicitly unboxed." - or - exists(Variable v | rebox(e, v) | - conv = - "This expression implicitly unboxes, updates, and reboxes the value of '" + v.getName() + "'." + e.getFile().isJavaSourceFile() and + ( + boxed(e) and conv = "This expression is implicitly boxed." + or + unboxed(e) and conv = "This expression is implicitly unboxed." + or + exists(Variable v | rebox(e, v) | + conv = + "This expression implicitly unboxes, updates, and reboxes the value of '" + v.getName() + + "'." + ) ) select e, conv diff --git a/java/ql/src/change-notes/2022-11-03-regex-injection.md b/java/ql/src/change-notes/2022-11-03-regex-injection.md new file mode 100644 index 00000000000..759aa2a86e1 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-03-regex-injection.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* The query, `java/regex-injection`, has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @edvraa](https://github.com/github/codeql/pull/5704). diff --git a/java/ql/src/change-notes/2022-11-12-android-webview-file-access.md b/java/ql/src/change-notes/2022-11-12-android-webview-file-access.md new file mode 100644 index 00000000000..3e8777e60cd --- /dev/null +++ b/java/ql/src/change-notes/2022-11-12-android-webview-file-access.md @@ -0,0 +1,5 @@ +--- +category: newQuery +--- +* Added a new query `java/android-websettings-file-access` to detect configurations that enable file system access in Android WebViews. + diff --git a/java/ql/src/change-notes/2022-11-12-websettings-setjavascript-enabled.md b/java/ql/src/change-notes/2022-11-12-websettings-setjavascript-enabled.md new file mode 100644 index 00000000000..58579f006c4 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-12-websettings-setjavascript-enabled.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/android-websettings-javascript-enabled`, to detect if JavaScript execution is enabled in an Android WebView. diff --git a/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md b/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md new file mode 100644 index 00000000000..5d060b06076 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-21-disabled-maven-repositories.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/maven/non-https-url` no longer alerts about disabled repositories. diff --git a/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md b/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md new file mode 100644 index 00000000000..20612e86325 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-22-bitwise-implicit-intent-flags.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed an issue in the query `java/android/implicit-pendingintents` by which an implicit Pending Intent marked as immutable was not correctly recognized as such. diff --git a/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md b/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md new file mode 100644 index 00000000000..c99d7168297 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-25-NamingConventionsRefTypes-kotlin.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/misnamed-type` is now enabled for Kotlin. diff --git a/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md b/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md new file mode 100644 index 00000000000..25977b2e807 --- /dev/null +++ b/java/ql/src/change-notes/2022-11-25-NonSerializableField-kotlin.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/non-serializable-field` is now enabled for Kotlin. diff --git a/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md new file mode 100644 index 00000000000..83bfcf96e20 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-01-supported-external-apis-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase. diff --git a/java/ql/src/change-notes/2022-12-12-java-mad-metrics-query.md b/java/ql/src/change-notes/2022-12-12-java-mad-metrics-query.md new file mode 100644 index 00000000000..8d4dd5d77e1 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-12-java-mad-metrics-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/summary/generated-vs-manual-coverage`, to expose metrics for the number of API endpoints covered by generated versus manual MaD models. diff --git a/java/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md b/java/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md new file mode 100644 index 00000000000..39532da22c8 --- /dev/null +++ b/java/ql/src/change-notes/2022-12-15-rename-mad-extensibles.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The extensible predicates for Models as Data have been renamed (the `ext` prefix has been removed). As an example `extSummaryModel` has been renamed to `summaryModel`. \ No newline at end of file diff --git a/java/ql/src/change-notes/2022-10-19-insufficient-key-size.md b/java/ql/src/change-notes/released/0.4.4.md similarity index 58% rename from java/ql/src/change-notes/2022-10-19-insufficient-key-size.md rename to java/ql/src/change-notes/released/0.4.4.md index e117b5b5941..849452aa9c0 100644 --- a/java/ql/src/change-notes/2022-10-19-insufficient-key-size.md +++ b/java/ql/src/change-notes/released/0.4.4.md @@ -1,4 +1,6 @@ ---- -category: newQuery ---- +## 0.4.4 + +### New Queries + * The query `java/insufficient-key-size` has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4926). +* Added a new query, `java/android/sensitive-keyboard-cache`, to detect instances of sensitive information possibly being saved to the Android keyboard cache. diff --git a/java/ql/src/change-notes/released/0.4.5.md b/java/ql/src/change-notes/released/0.4.5.md new file mode 100644 index 00000000000..7ba9b2e8ade --- /dev/null +++ b/java/ql/src/change-notes/released/0.4.5.md @@ -0,0 +1,3 @@ +## 0.4.5 + +No user-facing changes. diff --git a/java/ql/src/change-notes/released/0.4.6.md b/java/ql/src/change-notes/released/0.4.6.md new file mode 100644 index 00000000000..ae160f06a20 --- /dev/null +++ b/java/ql/src/change-notes/released/0.4.6.md @@ -0,0 +1,5 @@ +## 0.4.6 + +### Minor Analysis Improvements + +* Kotlin extraction will now fail if the Kotlin version in use is at least 1.7.30. This is to ensure using an as-yet-unsupported version is noticable, rather than silently failing to extract Kotlin code and therefore producing false-negative results. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 1ec9c4ea5d9..2b842473675 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.3 +lastReleaseVersion: 0.4.6 diff --git a/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql index 7b70a2e47d9..369833a4df2 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql @@ -19,159 +19,8 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.ExternalFlow import DataFlow::PathGraph -private class Log4jLoggingSinkModels extends SinkModelCsv { - override predicate row(string row) { - row = - [ - // org.apache.logging.log4j.Logger - "org.apache.logging.log4j;Logger;true;" + - ["debug", "error", "fatal", "info", "trace", "warn"] + - [ - ";(CharSequence);;Argument[0];log4j;manual", - ";(CharSequence,Throwable);;Argument[0];log4j;manual", - ";(Marker,CharSequence);;Argument[1];log4j;manual", - ";(Marker,CharSequence,Throwable);;Argument[1];log4j;manual", - ";(Marker,Message);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier);;Argument[1];log4j;manual", - ";(Marker,MessageSupplier,Throwable);;Argument[1];log4j;manual", - ";(Marker,Object);;Argument[1];log4j;manual", - ";(Marker,Object,Throwable);;Argument[1];log4j;manual", - ";(Marker,String);;Argument[1];log4j;manual", - ";(Marker,String,Object[]);;Argument[1..2];log4j;manual", - ";(Marker,String,Object);;Argument[1..2];log4j;manual", - ";(Marker,String,Object,Object);;Argument[1..3];log4j;manual", - ";(Marker,String,Object,Object,Object);;Argument[1..4];log4j;manual", - ";(Marker,String,Object,Object,Object,Object);;Argument[1..5];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object);;Argument[1..6];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];log4j;manual", - ";(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];log4j;manual", - ";(Marker,String,Supplier);;Argument[1..2];log4j;manual", - ";(Marker,String,Throwable);;Argument[1];log4j;manual", - ";(Marker,Supplier);;Argument[1];log4j;manual", - ";(Marker,Supplier,Throwable);;Argument[1];log4j;manual", - ";(MessageSupplier);;Argument[0];log4j;manual", - ";(MessageSupplier,Throwable);;Argument[0];log4j;manual", - ";(Message);;Argument[0];log4j;manual", - ";(Message,Throwable);;Argument[0];log4j;manual", ";(Object);;Argument[0];log4j;manual", - ";(Object,Throwable);;Argument[0];log4j;manual", ";(String);;Argument[0];log4j;manual", - ";(String,Object[]);;Argument[0..1];log4j;manual", - ";(String,Object);;Argument[0..1];log4j;manual", - ";(String,Object,Object);;Argument[0..2];log4j;manual", - ";(String,Object,Object,Object);;Argument[0..3];log4j;manual", - ";(String,Object,Object,Object,Object);;Argument[0..4];log4j;manual", - ";(String,Object,Object,Object,Object,Object);;Argument[0..5];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];log4j;manual", - ";(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];log4j;manual", - ";(String,Supplier);;Argument[0..1];log4j;manual", - ";(String,Throwable);;Argument[0];log4j;manual", - ";(Supplier);;Argument[0];log4j;manual", - ";(Supplier,Throwable);;Argument[0];log4j;manual" - ], - "org.apache.logging.log4j;Logger;true;log" + - [ - ";(Level,CharSequence);;Argument[1];log4j;manual", - ";(Level,CharSequence,Throwable);;Argument[1];log4j;manual", - ";(Level,Marker,CharSequence);;Argument[2];log4j;manual", - ";(Level,Marker,CharSequence,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Message);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier);;Argument[2];log4j;manual", - ";(Level,Marker,MessageSupplier,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Object);;Argument[2];log4j;manual", - ";(Level,Marker,Object,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,String);;Argument[2];log4j;manual", - ";(Level,Marker,String,Object[]);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Object);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Object,Object);;Argument[2..4];log4j;manual", - ";(Level,Marker,String,Object,Object,Object);;Argument[2..5];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object);;Argument[2..6];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object);;Argument[2..7];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object);;Argument[2..8];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object);;Argument[2..9];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..10];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..11];log4j;manual", - ";(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[2..12];log4j;manual", - ";(Level,Marker,String,Supplier);;Argument[2..3];log4j;manual", - ";(Level,Marker,String,Throwable);;Argument[2];log4j;manual", - ";(Level,Marker,Supplier);;Argument[2];log4j;manual", - ";(Level,Marker,Supplier,Throwable);;Argument[2];log4j;manual", - ";(Level,Message);;Argument[1];log4j;manual", - ";(Level,MessageSupplier);;Argument[1];log4j;manual", - ";(Level,MessageSupplier,Throwable);;Argument[1];log4j;manual", - ";(Level,Message);;Argument[1];log4j;manual", - ";(Level,Message,Throwable);;Argument[1];log4j;manual", - ";(Level,Object);;Argument[1];log4j;manual", - ";(Level,Object);;Argument[1];log4j;manual", - ";(Level,String);;Argument[1];log4j;manual", - ";(Level,Object,Throwable);;Argument[1];log4j;manual", - ";(Level,String);;Argument[1];log4j;manual", - ";(Level,String,Object[]);;Argument[1..2];log4j;manual", - ";(Level,String,Object);;Argument[1..2];log4j;manual", - ";(Level,String,Object,Object);;Argument[1..3];log4j;manual", - ";(Level,String,Object,Object,Object);;Argument[1..4];log4j;manual", - ";(Level,String,Object,Object,Object,Object);;Argument[1..5];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object);;Argument[1..6];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object);;Argument[1..7];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object);;Argument[1..8];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..9];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..10];log4j;manual", - ";(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[1..11];log4j;manual", - ";(Level,String,Supplier);;Argument[1..2];log4j;manual", - ";(Level,String,Throwable);;Argument[1];log4j;manual", - ";(Level,Supplier);;Argument[1];log4j;manual", - ";(Level,Supplier,Throwable);;Argument[1];log4j;manual" - ], "org.apache.logging.log4j;Logger;true;entry;(Object[]);;Argument[0];log4j;manual", - "org.apache.logging.log4j;Logger;true;logMessage;(Level,Marker,String,StackTraceElement,Message,Throwable);;Argument[4];log4j;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,Marker,String,Object[]);;Argument[2..3];log4j;manual", - "org.apache.logging.log4j;Logger;true;printf;(Level,String,Object[]);;Argument[1..2];log4j;manual", - // org.apache.logging.log4j.LogBuilder - "org.apache.logging.log4j;LogBuilder;true;log;(CharSequence);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Message);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Object);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String);;Argument[0];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object[]);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object);;Argument[0..2];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object);;Argument[0..3];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object);;Argument[0..4];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object);;Argument[0..5];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object);;Argument[0..6];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..10];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(String,Supplier[]);;Argument[0..1];log4j;manual", - "org.apache.logging.log4j;LogBuilder;true;log;(Supplier);;Argument[0];log4j;manual", - // org.apache.logging.log4j.ThreadContext - "org.apache.logging.log4j;ThreadContext;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;ThreadContext;false;putIfNull;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;ThreadContext;false;putAll;;;Argument[0];log4j;manual", - // org.apache.logging.log4j.CloseableThreadContext - "org.apache.logging.log4j;CloseableThreadContext;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext;false;putAll;;;Argument[0];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext$Instance;false;put;;;Argument[1];log4j;manual", - "org.apache.logging.log4j;CloseableThreadContext$Instance;false;putAll;;;Argument[0];log4j;manual", - ] - } -} - -class Log4jInjectionSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.apache.logging.log4j.message;MapMessage;true;with;;;Argument[1];Argument[-1];taint;manual", - "org.apache.logging.log4j.message;MapMessage;true;with;;;Argument[-1];ReturnValue;value;manual", - "org.apache.logging.log4j.message;MapMessage;true;put;;;Argument[1];Argument[-1];taint;manual", - "org.apache.logging.log4j.message;MapMessage;true;putAll;;;Argument[0].MapValue;Argument[-1];taint;manual", - ] - } +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "log4j-injection" } } /** A data flow sink for unvalidated user input that is used to log messages. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql index fff9a3b3613..9c976c8dce7 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql @@ -12,12 +12,17 @@ */ import java +import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.PathCreation import JFinalController import semmle.code.java.security.PathSanitizer import DataFlow::PathGraph +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "file-path-injection" } +} + /** A complementary sanitizer that protects against path traversal using path normalization. */ class PathNormalizeSanitizer extends MethodAccess { PathNormalizeSanitizer() { diff --git a/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll b/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll index df3b77cddaa..035039046f1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-073/JFinalController.qll @@ -1,5 +1,4 @@ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources /** The class `com.jfinal.core.Controller`. */ @@ -61,24 +60,3 @@ private class SetToGetAttributeStep extends AdditionalValueStep { ) } } - -/** Remote flow source models relating to `JFinal`. */ -private class JFinalControllerSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "com.jfinal.core;Controller;true;getCookie" + ["", "Object", "Objects", "ToInt", "ToLong"] + - ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getFile" + ["", "s"] + ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getHeader;;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getKv;;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;getPara" + - [ - "", "Map", "ToBoolean", "ToDate", "ToInt", "ToLong", "Values", "ValuesToInt", - "ValuesToLong" - ] + ";;;ReturnValue;remote;manual", - "com.jfinal.core;Controller;true;get" + ["", "Int", "Long", "Boolean", "Date"] + - ";;;ReturnValue;remote;manual" - ] - } -} diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index 3351af22a25..b6bc910484b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -86,7 +86,7 @@ bindingset[unsafeExpression] predicate isMybatisCollectionTypeSqlInjection( DataFlow::Node node, MethodAccess ma, string unsafeExpression ) { - not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and + not unsafeExpression.regexpMatch("\\$\\{\\s*" + getAMybatisConfigurationVariableKey() + "\\s*\\}") and // The parameter type of the MyBatis method parameter is Map or List or Array. // SQL injection vulnerability caused by improper use of this parameter. // e.g. @@ -120,7 +120,7 @@ bindingset[unsafeExpression] predicate isMybatisXmlOrAnnotationSqlInjection( DataFlow::Node node, MethodAccess ma, string unsafeExpression ) { - not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and + not unsafeExpression.regexpMatch("\\$\\{\\s*" + getAMybatisConfigurationVariableKey() + "\\s*\\}") and ( // The method parameters use `@Param` annotation. Due to improper use of this parameter, SQL injection vulnerabilities are caused. // e.g. @@ -128,16 +128,23 @@ predicate isMybatisXmlOrAnnotationSqlInjection( // ```java // @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR}) // void test(@Param("orderby") String name); + // + // @Select(select id,name from test where name = ${ user . name }) + // void test(@Param("user") User u); // ``` exists(Annotation annotation | unsafeExpression - .matches("${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() + - "%}") and + .regexpMatch("\\$\\{\\s*" + + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() + + "\\b[^}]*\\}") and annotation.getType() instanceof TypeParam and - ma.getAnArgument() = node.asExpr() + ma.getAnArgument() = node.asExpr() and + annotation.getTarget() = + ma.getMethod().getParameter(node.asExpr().(Argument).getParameterPos()) ) or // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n]. + // When compiled with '-parameters' compiler option, the parameter can be reflected in SQL statement as named in method signature. // e.g. // // ```java @@ -147,9 +154,12 @@ predicate isMybatisXmlOrAnnotationSqlInjection( exists(int i | not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and ( - unsafeExpression.matches("${param" + (i + 1) + "%}") + unsafeExpression.regexpMatch("\\$\\{\\s*param" + (i + 1) + "\\b[^}]*\\}") or - unsafeExpression.matches("${arg" + i + "%}") + unsafeExpression.regexpMatch("\\$\\{\\s*arg" + i + "\\b[^}]*\\}") + or + unsafeExpression + .regexpMatch("\\$\\{\\s*" + ma.getMethod().getParameter(i).getName() + "\\b[^}]*\\}") ) and ma.getArgument(i) = node.asExpr() ) @@ -164,7 +174,7 @@ predicate isMybatisXmlOrAnnotationSqlInjection( exists(int i, RefType t | not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and ma.getMethod().getParameterType(i).getName() = t.getName() and - unsafeExpression.matches("${" + t.getAField().getName() + "%}") and + unsafeExpression.regexpMatch("\\$\\{\\s*" + t.getAField().getName() + "\\b[^}]*\\}") and ma.getArgument(i) = node.asExpr() ) or diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll index 44e0d7fd96f..bd177b30213 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll @@ -6,6 +6,10 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.frameworks.android.WebView +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "android-web-resource-response" } +} + /** * The Android class `android.webkit.WebResourceRequest` for handling web requests. */ @@ -68,14 +72,3 @@ private class FetchUrlStep extends AdditionalValueStep { ) } } - -/** Value/taint steps relating to url loading and file reading in an Android application. */ -private class LoadUrlSummaries extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.io;FileInputStream;true;FileInputStream;;;Argument[0];Argument[-1];taint;manual", - "android.webkit;WebResourceRequest;false;getUrl;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} diff --git a/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql b/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql index c3af26f8ff4..a6d2049bd16 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-299/DisabledRevocationChecking.ql @@ -1,5 +1,5 @@ /** - * @name Disabled ceritificate revocation checking + * @name Disabled certificate revocation checking * @description Using revoked certificates is dangerous. * Therefore, revocation status of certificates in a chain should be checked. * @kind path-problem diff --git a/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll b/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll index b16142f3856..09db11dd40b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-321/HardcodedJwtKey.qll @@ -6,6 +6,10 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "hardcoded-jwt-key" } +} + /** The class `com.auth0.jwt.JWT`. */ class Jwt extends RefType { Jwt() { this.hasQualifiedName("com.auth0.jwt", "JWT") } @@ -125,21 +129,3 @@ class HardcodedJwtKeyConfiguration extends TaintTracking::Configuration { ) } } - -/** Taint model related to verifying JWT tokens. */ -private class VerificationFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "com.auth0.jwt.interfaces;Verification;true;build;;;Argument[-1];ReturnValue;taint;manual", - "com.auth0.jwt.interfaces;Verification;true;" + - ["acceptLeeway", "acceptExpiresAt", "acceptNotBefore", "acceptIssuedAt", "ignoreIssuedAt"] - + ";;;Argument[-1];ReturnValue;value;manual", - "com.auth0.jwt.interfaces;Verification;true;with" + - [ - "Issuer", "Subject", "Audience", "AnyOfAudience", "ClaimPresence", "Claim", - "ArrayClaim", "JWTId" - ] + ";;;Argument[-1];ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll index 5e4df693a00..39d27be133b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll @@ -81,8 +81,7 @@ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink { } /** A data flow sink for sql operation. */ -private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink { - SqlOperationSink() { this instanceof QueryInjectionSink } +private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink instanceof QueryInjectionSink { } /** A method that split string. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp b/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp new file mode 100644 index 00000000000..bf0c2d4ef2f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp @@ -0,0 +1,48 @@ + + + + + +

    The Thread.sleep method is used to pause the execution of current thread for +specified time. When the sleep time is user-controlled, especially in the web application context, +it can be abused to cause all of a server's threads to sleep, leading to denial of service.

    +
    + + +

    To guard against this attack, consider specifying an upper range of allowed sleep time or adopting +the producer/consumer design pattern with Object.wait method to avoid performance +problems or even resource exhaustion. For more information, refer to the concurrency tutorial of Oracle +listed below or java/ql/src/Likely Bugs/Concurrency queries of CodeQL.

    +
    + + +

    The following example shows a bad situation and a good situation respectively. In the bad situation, +a thread sleep time comes directly from user input. In the good situation, an upper +range check on the maximum sleep time allowed is enforced.

    + +
    + + +
  • +Snyk: +Denial of Service (DoS) +in com.googlecode.gwtupload:gwtupload. +
  • +
  • +gwtupload: +[Fix DOS issue] Updating the +AbstractUploadListener.java file. +
  • +
  • +The blog of a gypsy engineer: + +CVE-2019-17555: DoS via Retry-After header in Apache Olingo. +
  • +
  • +Oracle: +The Java Concurrency Tutorials +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.ql b/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.ql index 3c3c58da449..f66235994b0 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.ql @@ -3,7 +3,7 @@ * @description Using user input directly to control a thread's sleep time could lead to * performance problems or even resource exhaustion. * @kind path-problem - * @id java/thread-resource-abuse + * @id java/local-thread-resource-abuse * @problem.severity recommendation * @tags security * external/cwe/cwe-400 diff --git a/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll b/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll index e4dd7458951..3201f9483e4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll @@ -6,26 +6,8 @@ private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSteps import semmle.code.java.controlflow.Guards -/** `java.lang.Math` data model for value comparison in the new CSV format. */ -private class MathCompDataModel extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Math;false;min;;;Argument[0..1];ReturnValue;value;manual", - "java.lang;Math;false;max;;;Argument[0..1];ReturnValue;value;manual" - ] - } -} - -/** Thread pause data model in the new CSV format. */ -private class PauseThreadDataModel extends SinkModelCsv { - override predicate row(string row) { - row = - [ - "java.lang;Thread;true;sleep;;;Argument[0];thread-pause;manual", - "java.util.concurrent;TimeUnit;true;sleep;;;Argument[0];thread-pause;manual" - ] - } +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "thread-resource-abuse" } } /** A sink representing methods pausing a thread. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll index aa2999a9955..bff6a0a3893 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll @@ -6,6 +6,10 @@ private import semmle.code.java.dataflow.StringPrefixes private import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions private import experimental.semmle.code.java.frameworks.SpringResource +private class ActiveModels extends ActiveExperimentalModels { + ActiveModels() { this = "unsafe-url-forward" } +} + /** A sink for unsafe URL forward vulnerabilities. */ abstract class UnsafeUrlForwardSink extends DataFlow::Node { } @@ -161,52 +165,3 @@ private class SpringUrlForwardSink extends UnsafeUrlForwardSink { this.asExpr() = any(ForwardPrefix fp).getAnAppendedExpression() } } - -/** Source model of remote flow source from `getServletPath`. */ -private class ServletGetPathSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "javax.servlet.http;HttpServletRequest;true;getServletPath;;;ReturnValue;remote;manual", - "jakarta.servlet.http;HttpServletRequest;true;getServletPath;;;ReturnValue;remote;manual" - ] - } -} - -/** Taint model related to `java.nio.file.Path` and `io.undertow.server.handlers.resource.Resource`. */ -private class FilePathFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual", - "java.nio.file;Path;true;resolve;;;Argument[-1..0];ReturnValue;taint;manual", - "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual", - "java.nio.file;Path;true;toString;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getFile;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getFilePath;;;Argument[-1];ReturnValue;taint;manual", - "io.undertow.server.handlers.resource;Resource;true;getPath;;;Argument[-1];ReturnValue;taint;manual" - ] - } -} - -/** Taint models related to resource loading in Spring. */ -private class LoadSpringResourceFlowStep extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "org.springframework.core.io;ClassPathResource;false;ClassPathResource;;;Argument[0];Argument[-1];taint;manual", - "org.springframework.core.io;ResourceLoader;true;getResource;;;Argument[0];ReturnValue;taint;manual", - "org.springframework.core.io;Resource;true;createRelative;;;Argument[0];ReturnValue;taint;manual" - ] - } -} - -/** Sink models for methods that load Spring resources. */ -private class SpringResourceCsvSink extends SinkModelCsv { - override predicate row(string row) { - row = - // Get spring resource - "org.springframework.core.io;ClassPathResource;true;" + - ["getFilename", "getPath", "getURL", "resolveURL"] + ";;;Argument[-1];get-resource;manual" - } -} diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll index 21a44ebbb8f..e1c802c0245 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll @@ -8,6 +8,10 @@ import semmle.code.java.controlflow.Guards import semmle.code.java.security.UrlRedirect import Regex +private class ActivateModels extends ActiveExperimentalModels { + ActivateModels() { this = "permissive-dot-regex-query" } +} + /** A string that ends with `.*` not prefixed with `\`. */ private class PermissiveDotStr extends StringLiteral { PermissiveDotStr() { @@ -19,20 +23,6 @@ private class PermissiveDotStr extends StringLiteral { } } -/** Remote flow sources obtained from the URI of a servlet request. */ -private class GetServletUriSource extends SourceModelCsv { - override predicate row(string row) { - row = - [ - "javax.servlet.http;HttpServletRequest;false;getPathInfo;();;ReturnValue;uri-path;manual", - "javax.servlet.http;HttpServletRequest;false;getPathTranslated;();;ReturnValue;uri-path;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURI;();;ReturnValue;uri-path;manual", - "javax.servlet.http;HttpServletRequest;false;getRequestURL;();;ReturnValue;uri-path;manual", - "javax.servlet.http;HttpServletRequest;false;getServletPath;();;ReturnValue;uri-path;manual" - ] - } -} - /** The qualifier of a request dispatch method call. */ private class UrlDispatchSink extends UrlRedirectSink { UrlDispatchSink() { diff --git a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.java b/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.java deleted file mode 100644 index 387648a443e..00000000000 --- a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.demo; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class DemoApplication { - - @GetMapping("/string1") - public String string1(@RequestParam(value = "input", defaultValue = "test") String input, - @RequestParam(value = "pattern", defaultValue = ".*") String pattern) { - // BAD: Unsanitized user input is used to construct a regular expression - if (input.matches("^" + pattern + "=.*$")) - return "match!"; - - return "doesn't match!"; - } - - @GetMapping("/string2") - public String string2(@RequestParam(value = "input", defaultValue = "test") String input, - @RequestParam(value = "pattern", defaultValue = ".*") String pattern) { - // GOOD: User input is sanitized before constructing the regex - if (input.matches("^" + escapeSpecialRegexChars(pattern) + "=.*$")) - return "match!"; - - return "doesn't match!"; - } - - Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\]><-=!.+*?^$\\\\|]"); - - String escapeSpecialRegexChars(String str) { - return SPECIAL_REGEX_CHARS.matcher(str).replaceAll("\\\\$0"); - } -} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.ql deleted file mode 100644 index f60e5d9070b..00000000000 --- a/java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.ql +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @name Regular expression injection - * @description User input should not be used in regular expressions without first being sanitized, - * otherwise a malicious user may be able to provide a regex that could require - * exponential time on certain inputs. - * @kind path-problem - * @problem.severity error - * @precision high - * @id java/regex-injection - * @tags security - * external/cwe/cwe-730 - * external/cwe/cwe-400 - */ - -import java -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.dataflow.TaintTracking -import DataFlow::PathGraph - -/** - * A data flow sink for untrusted user input used to construct regular expressions. - */ -class RegexSink extends DataFlow::ExprNode { - RegexSink() { - exists(MethodAccess ma, Method m | m = ma.getMethod() | - ( - m.getDeclaringType() instanceof TypeString and - ( - ma.getArgument(0) = this.asExpr() and - m.hasName(["matches", "split", "replaceFirst", "replaceAll"]) - ) - or - m.getDeclaringType().hasQualifiedName("java.util.regex", "Pattern") and - ( - ma.getArgument(0) = this.asExpr() and - m.hasName(["compile", "matches"]) - ) - or - m.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "RegExUtils") and - ( - ma.getArgument(1) = this.asExpr() and - m.getParameterType(1) instanceof TypeString and - m.hasName([ - "removeAll", "removeFirst", "removePattern", "replaceAll", "replaceFirst", - "replacePattern" - ]) - ) - ) - ) - } -} - -abstract class Sanitizer extends DataFlow::ExprNode { } - -/** - * A call to a function whose name suggests that it escapes regular - * expression meta-characters. - */ -class RegExpSanitizationCall extends Sanitizer { - RegExpSanitizationCall() { - exists(string calleeName, string sanitize, string regexp | - calleeName = this.asExpr().(Call).getCallee().getName() and - sanitize = "(?:escape|saniti[sz]e)" and - regexp = "regexp?" - | - calleeName - .regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize + - ".*)") - ) - } -} - -/** - * A taint-tracking configuration for untrusted user input used to construct regular expressions. - */ -class RegexInjectionConfiguration extends TaintTracking::Configuration { - RegexInjectionConfiguration() { this = "RegexInjectionConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof RegexSink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - -from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c -where c.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", - source.getNode(), "user-provided value" diff --git a/java/ql/src/experimental/semmle/code/java/frameworks/SpringResource.qll b/java/ql/src/experimental/semmle/code/java/frameworks/SpringResource.qll index e8c86a26512..a4f53284d5d 100644 --- a/java/ql/src/experimental/semmle/code/java/frameworks/SpringResource.qll +++ b/java/ql/src/experimental/semmle/code/java/frameworks/SpringResource.qll @@ -3,7 +3,6 @@ */ import java -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources /** A utility class for resolving resource locations to files in the file system in the Spring framework. */ diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 87267893413..9017221edc3 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.4-dev +version: 0.5.0-dev groups: - java - queries diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll index 046debc5019..f90bbf2c908 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCase.qll @@ -12,7 +12,7 @@ private import FlowTestCaseSupportMethods /** * A CSV row to generate tests for. Users should extend this to define which - * tests to generate. Rows specified here should also satisfy `SummaryModelCsv.row`. + * tests to generate. There should already exist summaries for the rows specified here. */ class TargetSummaryModelCsv extends Unit { /** @@ -21,12 +21,32 @@ class TargetSummaryModelCsv extends Unit { abstract predicate row(string r); } +/** Holds if a summary model `row` exists for the given parameters. */ +bindingset[row] +predicate summaryModelRow( + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance, string row +) { + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and + row = + package + ";" // + + type + ";" // + + subtypes.toString() + ";" // + + name + ";" // + + signature + ";" // + + ext + ";" // + + input + ";" // + + output + ";" // + + kind + ";" // + + provenance +} + /** - * Gets a CSV row for which a test has been requested, but `SummaryModelCsv.row` does not hold of it. + * Gets a CSV row for which a test has been requested, but where a summary has not already been defined. */ -query string missingSummaryModelCsv() { +query string missingSummaryModel() { any(TargetSummaryModelCsv target).row(result) and - not any(SummaryModelCsv model).row(result) + not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) } /** @@ -64,8 +84,8 @@ private newtype TTestCase = string inputSpec, string outputSpec | any(TargetSummaryModelCsv tsmc).row(row) and - summaryModel(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind, _, - row) and + summaryModelRow(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind, + _, row) and callable = interpretElement(namespace, type, subtypes, name, signature, ext) and Private::External::interpretSpec(inputSpec, input) and Private::External::interpretSpec(outputSpec, output) diff --git a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll index 713c484ff4b..437923c1d1b 100644 --- a/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll +++ b/java/ql/src/utils/flowtestcasegenerator/FlowTestCaseSupportMethods.qll @@ -4,7 +4,6 @@ import java private import semmle.code.java.dataflow.internal.DataFlowUtil -private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSummary private import semmle.code.java.dataflow.internal.FlowSummaryImpl private import FlowTestCaseUtils @@ -97,12 +96,12 @@ abstract class SupportMethod extends string { int getPriority() { result = 50 } /** - * Gets the CSV row describing this support method if it is needed to set up the output for this test. + * Gets the data extension row describing this support method if it is needed to set up the output for this test. * - * For example, `newWithMapValue` will propagate a value from `Argument[0]` to `MapValue of ReturnValue`, and `getMapValue` + * For example, `newWithMapValue` will propagate a value from `Argument[0]` to `ReturnValue.MapValue`, and `getMapValue` * will do the opposite. */ - string getCsvModel() { none() } + string getDataExtensionModel() { none() } } /** @@ -162,10 +161,11 @@ private class DefaultGetMethod extends GetMethod { result = "Object get" + contentToken(c) + "Default(Object container) { return null; }" } - override string getCsvModel() { + override string getDataExtensionModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;" + - getComponentSpec(SummaryComponent::content(c)) + "Argument[0].;ReturnValue;value;manual" + "\"generatedtest\", \"Test\", False, \"" + this.getName() + + "\", \"(Object)\", \"\", \"Argument[0]." + getComponentSpec(SummaryComponent::content(c)) + + "\", \"ReturnValue\", \"value\", \"manual\"" } } @@ -358,10 +358,11 @@ private class DefaultGenMethod extends GenMethod { result = "Object newWith" + contentToken(c) + "Default(Object element) { return null; }" } - override string getCsvModel() { + override string getDataExtensionModel() { result = - "generatedtest;Test;false;" + this.getName() + ";(Object);;Argument[0];" + - getComponentSpec(SummaryComponent::content(c)) + "ReturnValue.;value;manual" + "\"generatedtest\", \"Test\", False, \"" + this.getName() + + "\", \"(Object)\", \"\", \"Argument[0]\", \"ReturnValue." + + getComponentSpec(SummaryComponent::content(c)) + "\", \"value\", \"manual\"" } } diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index 38d90830bf5..fb10c934afd 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -16,7 +16,7 @@ if any(s == "--help" for s in sys.argv): GenerateFlowTestCase.py specsToTest.csv projectPom.xml outdir [--force] This generates test cases exercising function model specifications found in specsToTest.csv -producing files Test.java, test.ql and test.expected in outdir. +producing files Test.java, test.ql, test.ext.yml and test.expected in outdir. projectPom.xml should be a Maven pom sufficient to resolve the classes named in specsToTest.csv. Typically this means supplying a skeleton POM section that retrieves whatever jars @@ -24,7 +24,9 @@ contain the needed classes. If --force is present, existing files may be overwritten. -Requirements: `mvn` and `codeql` should both appear on your path. +Requirements: + - `mvn` and `codeql` should both appear on your path. + - `--additional-packs /path/to/semmle-code/ql` should be added to your `.config/codeql/config` file. After test generation completes, any lines in specsToTest.csv that didn't produce tests are output. If this happens, check the spelling of class and method names, and the syntax of input and output specifications. @@ -52,10 +54,11 @@ except Exception as e: resultJava = os.path.join(sys.argv[3], "Test.java") resultQl = os.path.join(sys.argv[3], "test.ql") +resultYml = os.path.join(sys.argv[3], "test.ext.yml") -if not force and (os.path.exists(resultJava) or os.path.exists(resultQl)): - print("Won't overwrite existing files '%s' or '%s'" % - (resultJava, resultQl), file=sys.stderr) +if not force and (os.path.exists(resultJava) or os.path.exists(resultQl) or os.path.exists(resultYml)): + print("Won't overwrite existing files '%s', '%s' or '%s'." % + (resultJava, resultQl, resultYml), file=sys.stderr) sys.exit(1) workDir = tempfile.mkdtemp() @@ -127,7 +130,13 @@ queryDir = os.path.join(workDir, "query") os.makedirs(queryDir) qlFile = os.path.join(queryDir, "gen.ql") with open(os.path.join(queryDir, "qlpack.yml"), "w") as f: - f.write("name: test-generation-query\nversion: 0.0.0\nlibraryPathDependencies: codeql/java-queries") + f.write("""name: test-generation-query +version: 0.0.0 +dependencies: + codeql/java-all: '*' + codeql/java-queries: '*' +""") + with open(qlFile, "w") as f: f.write( "import java\nimport utils.flowtestcasegenerator.GenerateFlowTestCase\n\nclass GenRow extends TargetSummaryModelCsv {\n\n\toverride predicate row(string r) {\n\t\tr = [\n") @@ -163,9 +172,9 @@ def getTuples(queryName, jsonResult, fname): with open(generatedJson, "r") as f: generateOutput = json.load(f) expectedTables = ("getTestCase", "getASupportMethodModel", - "missingSummaryModelCsv", "getAParseFailure", "noTestCaseGenerated") + "missingSummaryModel", "getAParseFailure", "noTestCaseGenerated") - testCaseRows, supportModelRows, missingSummaryModelCsvRows, parseFailureRows, noTestCaseGeneratedRows = \ + testCaseRows, supportModelRows, missingSummaryModelRows, parseFailureRows, noTestCaseGeneratedRows = \ tuple([getTuples(k, generateOutput, generatedJson) for k in expectedTables]) @@ -182,9 +191,9 @@ with open(generatedJson, "r") as f: print("Expected exactly one column in noTestCaseGenerated relation (got: %s)" % json.dumps(noTestCaseGeneratedRows), file=sys.stderr) - if len(missingSummaryModelCsvRows) != 0: - print("Tests for some CSV rows were requested that were not in scope (SummaryModelCsv.row does not hold):\n" + - "\n".join(r[0] for r in missingSummaryModelCsvRows)) + if len(missingSummaryModelRows) != 0: + print("Tests for some CSV rows were requested that were not in scope (a summary doesn't already exist):\n" + + "\n".join(r[0] for r in missingSummaryModelRows)) sys.exit(1) if len(parseFailureRows) != 0: print("The following rows failed to generate any test case. Check package, class and method name spelling, and argument and result specifications:\n%s" % @@ -207,11 +216,20 @@ def copyfile(fromName, toFileHandle): with open(resultQl, "w") as f: copyfile("testHeader.qlfrag", f) - if len(supportModelRows) != 0: - copyfile("testModelsHeader.qlfrag", f) - f.write(", ".join('"%s"' % - modelSpecRow[0].strip() for modelSpecRow in supportModelRows)) - copyfile("testModelsFooter.qlfrag", f) + +if len(supportModelRows) != 0: + # Make a test extension file + with open(resultYml, "w") as f: + models = "\n".join(' - [%s]' % + modelSpecRow[0].strip() for modelSpecRow in supportModelRows) + dataextensions = f"""extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: +{models} +""" + f.write(dataextensions) # Make an empty .expected file, since this is an inline-exectations test with open(os.path.join(sys.argv[3], "test.expected"), "w"): diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll index 9eb925be422..b06d9c60220 100644 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.qll @@ -13,33 +13,33 @@ private import FlowTestCaseSupportMethods private import FlowTestCaseUtils /** - * Gets a CSV row for which a test has been requested, and `SummaryModelCsv.row` does hold, but + * Gets a CSV row for which a test has been requested, and where there exists a summary, but * nonetheless we can't generate a test case for it, indicating we cannot resolve either the callable * spec or an input or output spec. */ query string getAParseFailure(string reason) { any(TargetSummaryModelCsv target).row(result) and - any(SummaryModelCsv model).row(result) and + summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and ( - not summaryModel(_, _, _, _, _, _, _, _, _, _, result) and + not summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and reason = "row could not be parsed" or exists( string namespace, string type, boolean subtypes, string name, string signature, string ext | - summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, result) and + summaryModelRow(namespace, type, subtypes, name, signature, ext, _, _, _, _, result) and not interpretElement(namespace, type, subtypes, name, signature, ext) instanceof Callable and reason = "callable could not be resolved" ) or exists(string inputSpec | - summaryModel(_, _, _, _, _, _, inputSpec, _, _, _, result) and + summaryModelRow(_, _, _, _, _, _, inputSpec, _, _, _, result) and not Private::External::interpretSpec(inputSpec, _) and reason = "input spec could not be parsed" ) or exists(string outputSpec | - summaryModel(_, _, _, _, _, _, _, outputSpec, _, _, result) and + summaryModelRow(_, _, _, _, _, _, _, outputSpec, _, _, result) and not Private::External::interpretSpec(outputSpec, _) and reason = "output spec could not be parsed" ) @@ -52,7 +52,7 @@ query string getAParseFailure(string reason) { */ query string noTestCaseGenerated() { any(TargetSummaryModelCsv target).row(result) and - any(SummaryModelCsv model).row(result) and + summaryModelRow(_, _, _, _, _, _, _, _, _, _, result) and not exists(getAParseFailure(_)) and not exists(any(TestCase tc).getATestSnippetForRow(result)) } @@ -85,12 +85,12 @@ SupportMethod getASupportMethod() { } /** - * Returns a CSV specification of the taint-/value-propagation behavior of a test support method (`get` or `newWith` method). + * Returns a data extension specification of the taint-/value-propagation behavior of a test support method (`get` or `newWith` method). */ -query string getASupportMethodModel() { result = getASupportMethod().getCsvModel() } +query string getASupportMethodModel() { result = getASupportMethod().getDataExtensionModel() } /** - * Gets a Java file body testing all requested CSV rows against whatever classes and methods they resolve against. + * Gets a Java file body testing all requested Models as Data rows against whatever classes and methods they resolve against. */ query string getTestCase() { result = diff --git a/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag deleted file mode 100644 index 77bc78669d2..00000000000 --- a/java/ql/src/utils/flowtestcasegenerator/testModelsFooter.qlfrag +++ /dev/null @@ -1,3 +0,0 @@ - ] - } -} diff --git a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag deleted file mode 100644 index a49dbbe5404..00000000000 --- a/java/ql/src/utils/flowtestcasegenerator/testModelsHeader.qlfrag +++ /dev/null @@ -1,5 +0,0 @@ -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", diff --git a/java/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql b/java/ql/src/utils/model-generator/CaptureNeutralModels.ql similarity index 60% rename from java/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql rename to java/ql/src/utils/model-generator/CaptureNeutralModels.ql index a6f6e5f26e5..96744de89b6 100644 --- a/java/ql/src/utils/model-generator/CaptureNegativeSummaryModels.ql +++ b/java/ql/src/utils/model-generator/CaptureNeutralModels.ql @@ -1,8 +1,8 @@ /** - * @name Capture negative summary models. - * @description Finds negative summary models to be used by other queries. + * @name Capture neutral models. + * @description Finds neutral models to be used by other queries. * @kind diagnostic - * @id java/utils/model-generator/negative-summary-models + * @id java/utils/model-generator/neutral-models * @tags model-generator */ diff --git a/java/ql/src/utils/model-generator/RegenerateModels.py b/java/ql/src/utils/model-generator/RegenerateModels.py index 55e9651b4ca..6bea57793a0 100755 --- a/java/ql/src/utils/model-generator/RegenerateModels.py +++ b/java/ql/src/utils/model-generator/RegenerateModels.py @@ -2,22 +2,19 @@ # Tool to regenerate existing framework CSV models. -from pathlib import Path import json import os -import requests import shutil import subprocess import tempfile import sys -defaultModelPath = "java/ql/lib/semmle/code/java/frameworks" lgtmSlugToModelFile = { # "apache/commons-beanutils": "apache/BeanUtilsGenerated.qll", # "apache/commons-codec": "apache/CodecGenerated.qll", # "apache/commons-lang": "apache/Lang3Generated.qll", - "apache/commons-io": "apache/IOGenerated.qll", + "apache/commons-io": "org.apache.commons.io", } @@ -36,13 +33,12 @@ def regenerateModel(lgtmSlug, extractedDb): print("ERROR: slug " + lgtmSlug + " is not mapped to a model file in script " + sys.argv[0]) sys.exit(1) - modelFile = defaultModelPath + "/" + lgtmSlugToModelFile[lgtmSlug] + modelFile = lgtmSlugToModelFile[lgtmSlug] codeQlRoot = findGitRoot() - targetModel = codeQlRoot + "/" + modelFile subprocess.check_call([codeQlRoot + "/java/ql/src/utils/model-generator/GenerateFlowModel.py", - "--with-summaries", "--with-sinks", - extractedDb, targetModel]) - print("Regenerated " + targetModel) + "--with-summaries", "--with-sinks", "--with-neutrals", + extractedDb, modelFile]) + print("Regenerated " + modelFile) shutil.rmtree(tmpDir) diff --git a/java/ql/src/utils/modelconverter/ConvertExtensions.py b/java/ql/src/utils/modelconverter/ConvertExtensions.py new file mode 100644 index 00000000000..c2d2e7b2e09 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ConvertExtensions.py @@ -0,0 +1,41 @@ +# Tool to generate data extensions files based on the existing models. +# Usage: +# python3 ConvertExtensions.py +# (1) A folder named `java/ql/lib/ext` will be created, if it doesn't already exist. +# (2) The converted models will be written to `java/ql/lib/ext`. One file for each namespace. + +import os +import subprocess +import sys +import tempfile + +# Add Models as Data script directory to sys.path. +gitroot = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip() +madpath = os.path.join(gitroot, "misc/scripts/models-as-data/") +sys.path.append(madpath) + +import helpers +import convert_extensions as extensions + +print('Running script to generate data extensions files from the existing MaD models.') +print('Making a dummy database.') + +# Configuration +language = "java" +workDir = tempfile.mkdtemp() +projectDir = os.path.join(workDir, "project") +emptyFile = os.path.join(workDir, "Empty.java") +dbDir = os.path.join(workDir, "db") + +# Make dummy project +with open(emptyFile, "w") as f: + f.write("class Empty {}") +helpers.run_cmd(['codeql', 'database', 'create', f'--language={language}', '-c', f'javac {emptyFile}', dbDir], "Failed to create dummy database.") + +print('Converting data extensions for Java.') +extensions.Converter(language, dbDir).run() + +print('Cleanup.') +# Cleanup - delete database. +helpers.remove_dir(dbDir) +print('Done.') \ No newline at end of file diff --git a/java/ql/src/utils/modelconverter/ExtractNeutrals.ql b/java/ql/src/utils/modelconverter/ExtractNeutrals.ql new file mode 100644 index 00000000000..ad7cef84f04 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractNeutrals.ql @@ -0,0 +1,14 @@ +/** + * @name Extract MaD neutral model rows. + * @description This extracts the Models as data neutral model rows. + * @id java/utils/modelconverter/generate-data-extensions-neutral + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from string package, string type, string name, string signature, string provenance +where + neutralModel(package, type, name, signature, provenance) and + provenance != "generated" +select package, type, name, signature, provenance order by package, type, name, signature diff --git a/java/ql/src/utils/modelconverter/ExtractSinks.ql b/java/ql/src/utils/modelconverter/ExtractSinks.ql new file mode 100644 index 00000000000..cbfd4f7cebb --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSinks.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD sink model rows. + * @description This extracts the Models as data sink model rows. + * @id java/utils/modelconverter/generate-data-extensions-sink + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string kind, string provenance +where + sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, input, kind, provenance order by + package, type, name, signature, input, kind diff --git a/java/ql/src/utils/modelconverter/ExtractSources.ql b/java/ql/src/utils/modelconverter/ExtractSources.ql new file mode 100644 index 00000000000..b74a97e3728 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSources.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD source model rows. + * @description This extracts the Models as data source model rows. + * @id java/utils/modelconverter/generate-data-extensions-source + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance +where + sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, output, kind, provenance order by + package, type, name, signature, output, kind diff --git a/java/ql/src/utils/modelconverter/ExtractSummaries.ql b/java/ql/src/utils/modelconverter/ExtractSummaries.ql new file mode 100644 index 00000000000..65af62b3259 --- /dev/null +++ b/java/ql/src/utils/modelconverter/ExtractSummaries.ql @@ -0,0 +1,17 @@ +/** + * @name Extract MaD summary model rows. + * @description This extracts the Models as data summary model rows. + * @id java/utils/modelconverter/generate-data-extensions-summary + */ + +import java +import semmle.code.java.dataflow.ExternalFlow + +from + string package, string type, boolean subtypes, string name, string signature, string ext, + string input, string output, string kind, string provenance +where + summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and + provenance != "generated" +select package, type, subtypes, name, signature, ext, input, output, kind, provenance order by + package, type, name, signature, input, output, kind diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index f40b028ba6d..893c62191b3 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -58,9 +58,7 @@ private string asSummaryModel(TargetApiSpecific api, string input, string output + "generated" } -string asNegativeSummaryModel(TargetApiSpecific api) { - result = asPartialNegativeModel(api) + "generated" -} +string asNeutralModel(TargetApiSpecific api) { result = asPartialNeutralModel(api) + "generated" } /** * Gets the value summary model for `api` with `input` and `output`. diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 6e9fe7c29b2..e8be963f0dc 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -39,15 +39,20 @@ private predicate isJdkInternal(J::CompilationUnit cu) { cu.getPackage().getName().matches("javax.swing%") or cu.getPackage().getName().matches("java.awt%") or cu.getPackage().getName().matches("sun%") or - cu.getPackage().getName().matches("jdk.%") or - cu.getPackage().getName().matches("java2d.%") or - cu.getPackage().getName().matches("build.tools.%") or - cu.getPackage().getName().matches("propertiesparser.%") or - cu.getPackage().getName().matches("org.jcp.%") or - cu.getPackage().getName().matches("org.w3c.%") or - cu.getPackage().getName().matches("org.ietf.jgss.%") or + cu.getPackage().getName().matches("jdk%") or + cu.getPackage().getName().matches("java2d%") or + cu.getPackage().getName().matches("build.tools%") or + cu.getPackage().getName().matches("propertiesparser%") or + cu.getPackage().getName().matches("org.jcp%") or + cu.getPackage().getName().matches("org.w3c%") or + cu.getPackage().getName().matches("org.ietf.jgss%") or cu.getPackage().getName().matches("org.xml.sax%") or + cu.getPackage().getName().matches("com.oracle%") or + cu.getPackage().getName().matches("org.omg%") or + cu.getPackage().getName().matches("org.relaxng%") or cu.getPackage().getName() = "compileproperties" or + cu.getPackage().getName() = "transparentruler" or + cu.getPackage().getName() = "genstubs" or cu.getPackage().getName() = "netscape.javascript" or cu.getPackage().getName() = "" } @@ -59,7 +64,9 @@ private predicate isRelevantForModels(J::Callable api) { not isInTestFile(api.getCompilationUnit().getFile()) and not isJdkInternal(api.getCompilationUnit()) and not api instanceof J::MainMethod and - not api instanceof J::StaticInitializer + not api instanceof J::StaticInitializer and + not exists(J::FunctionalExpr funcExpr | api = funcExpr.asMethod()) and + not api.(J::Constructor).isParameterless() } /** @@ -131,9 +138,9 @@ string asPartialModel(TargetApiSpecific api) { } /** - * Computes the first 4 columns for negative CSV rows. + * Computes the first 4 columns for neutral CSV rows. */ -string asPartialNegativeModel(TargetApiSpecific api) { +string asPartialNeutralModel(TargetApiSpecific api) { exists(string type, string name, string parameters | partialModel(api, type, name, parameters) and result = diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll index 4b5293e63cd..04e87d9a385 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll @@ -77,10 +77,10 @@ string captureFlow(DataFlowTargetApi api) { } /** - * Gets the negative summary for `api`, if any. - * A negative summary is generated, if there does not exist any positive flow. + * Gets the neutral summary for `api`, if any. + * A neutral model is generated, if there does not exist any summary model. */ string captureNoFlow(DataFlowTargetApi api) { not exists(captureFlow(api)) and - result = asNegativeSummaryModel(api) + result = asNeutralModel(api) } diff --git a/java/ql/src/utils/stub-generator/Stubs.qll b/java/ql/src/utils/stub-generator/Stubs.qll index 5c04dee0090..3aca6efa6d6 100644 --- a/java/ql/src/utils/stub-generator/Stubs.qll +++ b/java/ql/src/utils/stub-generator/Stubs.qll @@ -7,12 +7,17 @@ import java +/** Holds if `id` is a valid Java identifier. */ +bindingset[id] +private predicate isValidIdentifier(string id) { id.regexpMatch("[\\w_$]+") } + /** A type that should be in the generated code. */ abstract private class GeneratedType extends ClassOrInterface { GeneratedType() { not this instanceof AnonymousClass and not this.isLocal() and - not this.getPackage() instanceof ExcludedPackage + not this.getPackage() instanceof ExcludedPackage and + isValidIdentifier(this.getName()) } private string stubKeyword() { @@ -108,7 +113,8 @@ abstract private class GeneratedType extends ClassOrInterface { not result.isPrivate() and not result.isPackageProtected() and not result instanceof StaticInitializer and - not result instanceof InstanceInitializer + not result instanceof InstanceInitializer and + isValidIdentifier(result.getName()) } final Type getAGeneratedType() { @@ -493,11 +499,8 @@ private RefType getAReferencedType(RefType t) { } /** A top level type whose file should be stubbed */ -class GeneratedTopLevel extends TopLevelType { - GeneratedTopLevel() { - this = this.getSourceDeclaration() and - this instanceof GeneratedType - } +class GeneratedTopLevel extends TopLevelType instanceof GeneratedType { + GeneratedTopLevel() { this = this.getSourceDeclaration() } private TopLevelType getAnImportedType() { result = getAReferencedType(this).getSourceDeclaration() @@ -530,8 +533,6 @@ class GeneratedTopLevel extends TopLevelType { /** Creates a full stub for the file containing this type. */ string stubFile() { - result = - this.stubComment() + this.stubPackage() + this.stubImports() + this.(GeneratedType).getStub() + - "\n" + result = this.stubComment() + this.stubPackage() + this.stubImports() + super.getStub() + "\n" } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected index dfc923f9b58..dd3f886ccb1 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected @@ -1,16 +1,45 @@ edges | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjection.java:63:35:63:38 | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | MybatisSqlInjectionService.java:48:19:48:29 | name : String | +| MybatisSqlInjection.java:67:46:67:70 | name : String | MybatisSqlInjection.java:68:40:68:43 | name : String | +| MybatisSqlInjection.java:68:40:68:43 | name : String | MybatisSqlInjectionService.java:54:32:54:42 | name : String | +| MybatisSqlInjection.java:99:20:99:44 | name : String | MybatisSqlInjection.java:100:36:100:39 | name : String | +| MybatisSqlInjection.java:100:36:100:39 | name : String | MybatisSqlInjectionService.java:80:20:80:30 | name : String | +| MybatisSqlInjection.java:104:20:104:43 | age : String | MybatisSqlInjection.java:105:36:105:38 | age : String | +| MybatisSqlInjection.java:105:36:105:38 | age : String | MybatisSqlInjectionService.java:84:20:84:29 | age : String | +| MybatisSqlInjection.java:109:46:109:70 | name : String | MybatisSqlInjection.java:110:40:110:43 | name : String | +| MybatisSqlInjection.java:110:40:110:43 | name : String | MybatisSqlInjectionService.java:88:32:88:42 | name : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | MybatisSqlInjectionService.java:50:23:50:26 | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | +| MybatisSqlInjectionService.java:54:32:54:42 | name : String | MybatisSqlInjectionService.java:55:32:55:35 | name | +| MybatisSqlInjectionService.java:80:20:80:30 | name : String | MybatisSqlInjectionService.java:81:28:81:31 | name | +| MybatisSqlInjectionService.java:84:20:84:29 | age : String | MybatisSqlInjectionService.java:85:28:85:30 | age | +| MybatisSqlInjectionService.java:88:32:88:42 | name : String | MybatisSqlInjectionService.java:89:32:89:35 | name | nodes | MybatisSqlInjection.java:62:19:62:43 | name : String | semmle.label | name : String | | MybatisSqlInjection.java:63:35:63:38 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:67:46:67:70 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:68:40:68:43 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:99:20:99:44 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:100:36:100:39 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:104:20:104:43 | age : String | semmle.label | age : String | +| MybatisSqlInjection.java:105:36:105:38 | age : String | semmle.label | age : String | +| MybatisSqlInjection.java:109:46:109:70 | name : String | semmle.label | name : String | +| MybatisSqlInjection.java:110:40:110:43 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:48:19:48:29 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [] : String | semmle.label | hashMap [post update] [] : String | | MybatisSqlInjectionService.java:50:23:50:26 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap | +| MybatisSqlInjectionService.java:54:32:54:42 | name : String | semmle.label | name : String | +| MybatisSqlInjectionService.java:55:32:55:35 | name | semmle.label | name | +| MybatisSqlInjectionService.java:80:20:80:30 | name : String | semmle.label | name : String | +| MybatisSqlInjectionService.java:81:28:81:31 | name | semmle.label | name | +| MybatisSqlInjectionService.java:84:20:84:29 | age : String | semmle.label | age : String | +| MybatisSqlInjectionService.java:85:28:85:30 | age | semmle.label | age | +| MybatisSqlInjectionService.java:88:32:88:42 | name : String | semmle.label | name : String | +| MybatisSqlInjectionService.java:89:32:89:35 | name | semmle.label | name | subpaths #select | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:62:19:62:43 | name | this user input | SqlInjectionMapper.java:33:2:33:54 | Select | this SQL operation | +| MybatisSqlInjectionService.java:55:32:55:35 | name | MybatisSqlInjection.java:67:46:67:70 | name : String | MybatisSqlInjectionService.java:55:32:55:35 | name | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:67:46:67:70 | name | this user input | SqlInjectionMapper.java:36:2:36:72 | Select | this SQL operation | diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java index 624f27ad81d..856c1d0b299 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjection.java @@ -63,6 +63,11 @@ public class MybatisSqlInjection { mybatisSqlInjectionService.bad9(name); } + @GetMapping(value = "msi10") + public void bad10(@RequestParam Integer id, @RequestParam String name) { + mybatisSqlInjectionService.bad10(id, name); + } + @GetMapping(value = "good1") public List good1(Integer id) { List result = mybatisSqlInjectionService.good1(id); @@ -79,7 +84,7 @@ public class MybatisSqlInjection { public void badDelete(@RequestParam String name) { mybatisSqlInjectionService.badDelete(name); } - + @GetMapping(value = "badUpdate") public void badUpdate(@RequestParam String name) { mybatisSqlInjectionService.badUpdate(name); @@ -89,4 +94,19 @@ public class MybatisSqlInjection { public void badInsert(@RequestParam String name) { mybatisSqlInjectionService.badInsert(name); } + + @GetMapping(value = "good2") + public void good2(@RequestParam String name, @RequestParam Integer age) { + mybatisSqlInjectionService.good2(name, age); + } + + @GetMapping(value = "good3") + public void good3(@RequestParam String age) { + mybatisSqlInjectionService.good3(age); + } + + @GetMapping(value = "good4") + public void good4(@RequestParam Integer id, @RequestParam String name) { + mybatisSqlInjectionService.good4(id, name); + } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java index 89dbd599d71..6e334ea35dd 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/MybatisSqlInjectionService.java @@ -51,6 +51,10 @@ public class MybatisSqlInjectionService { sqlInjectionMapper.bad9(hashMap); } + public void bad10(Integer id, String name) { + sqlInjectionMapper.bad10(id, name); + } + public List good1(Integer id) { List result = sqlInjectionMapper.good1(id); return result; @@ -72,4 +76,16 @@ public class MybatisSqlInjectionService { public void badInsert(String input) { sqlInjectionMapper.badInsert(input); } + + public void good2(String name, Integer age){ + sqlInjectionMapper.good2(name, age); + } + + public void good3(String age){ + sqlInjectionMapper.good3(age); + } + + public void good4(Integer id, String name) { + sqlInjectionMapper.good4(id, name); + } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java index 5b159817297..a8f56b40bc3 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java @@ -33,30 +33,42 @@ public interface SqlInjectionMapper { @Select({"select * from test", "where id = ${name}"}) public Test bad9(HashMap map); + @Select({"select * from test where id = #{id} and name = '${ name }'"}) + String bad10(Integer id, String name); + List good1(Integer id); //using providers @SelectProvider( - type = MyBatisProvider.class, - method = "badSelect" + type = MyBatisProvider.class, + method = "badSelect" ) String badSelect(String input); @DeleteProvider( - type = MyBatisProvider.class, - method = "badDelete" + type = MyBatisProvider.class, + method = "badDelete" ) void badDelete(String input); @UpdateProvider( - type = MyBatisProvider.class, - method = "badUpdate" + type = MyBatisProvider.class, + method = "badUpdate" ) void badUpdate(String input); @InsertProvider( - type = MyBatisProvider.class, - method = "badInsert" + type = MyBatisProvider.class, + method = "badInsert" ) void badInsert(String input); + + @Select("select * from user_info where name = #{name} and age = ${age}") + String good2(@Param("name") String name, Integer age); + + @Select("select * from user_info where age = #{age}") + String good3(@Param("age") String age); + + @Select({"select * from test where id = #{id} and name = #{name}"}) + String good4(Integer id, String name); } diff --git a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.xml b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.xml index 3f3d1f9ba77..a0d8d7a7970 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.xml +++ b/java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.xml @@ -12,7 +12,7 @@ - and name = ${test.name,jdbcType=VARCHAR} + and name = ${ test . name , jdbcType = VARCHAR } and id = #{test.id} diff --git a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.expected deleted file mode 100644 index a795f1591ad..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.expected +++ /dev/null @@ -1,73 +0,0 @@ -edges -| RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... | -| RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern | -| RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern | -| RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern | -| RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern | -| RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern | -| RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern | -| RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:36:68:42 | pattern : String | -| RegexInjection.java:68:32:68:43 | foo(...) : String | RegexInjection.java:68:26:68:52 | ... + ... | -| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:68:32:68:43 | foo(...) : String | -| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:71:14:71:23 | str : String | -| RegexInjection.java:71:14:71:23 | str : String | RegexInjection.java:72:12:72:14 | str : String | -| RegexInjection.java:84:22:84:52 | getParameter(...) : String | RegexInjection.java:90:26:90:47 | ... + ... | -| RegexInjection.java:100:22:100:52 | getParameter(...) : String | RegexInjection.java:103:40:103:46 | pattern | -| RegexInjection.java:107:22:107:52 | getParameter(...) : String | RegexInjection.java:110:42:110:48 | pattern | -| RegexInjection.java:114:22:114:52 | getParameter(...) : String | RegexInjection.java:117:44:117:50 | pattern | -| RegexInjection.java:121:22:121:52 | getParameter(...) : String | RegexInjection.java:124:41:124:47 | pattern | -| RegexInjection.java:128:22:128:52 | getParameter(...) : String | RegexInjection.java:131:43:131:49 | pattern | -| RegexInjection.java:143:22:143:52 | getParameter(...) : String | RegexInjection.java:146:45:146:51 | pattern | -nodes -| RegexInjection.java:13:22:13:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:16:26:16:47 | ... + ... | semmle.label | ... + ... | -| RegexInjection.java:20:22:20:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:23:24:23:30 | pattern | semmle.label | pattern | -| RegexInjection.java:27:22:27:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:30:31:30:37 | pattern | semmle.label | pattern | -| RegexInjection.java:34:22:34:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:37:29:37:35 | pattern | semmle.label | pattern | -| RegexInjection.java:41:22:41:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:44:34:44:40 | pattern | semmle.label | pattern | -| RegexInjection.java:51:22:51:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:54:28:54:34 | pattern | semmle.label | pattern | -| RegexInjection.java:58:22:58:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:61:28:61:34 | pattern | semmle.label | pattern | -| RegexInjection.java:65:22:65:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:68:26:68:52 | ... + ... | semmle.label | ... + ... | -| RegexInjection.java:68:32:68:43 | foo(...) : String | semmle.label | foo(...) : String | -| RegexInjection.java:68:36:68:42 | pattern : String | semmle.label | pattern : String | -| RegexInjection.java:71:14:71:23 | str : String | semmle.label | str : String | -| RegexInjection.java:72:12:72:14 | str : String | semmle.label | str : String | -| RegexInjection.java:84:22:84:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:90:26:90:47 | ... + ... | semmle.label | ... + ... | -| RegexInjection.java:100:22:100:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:103:40:103:46 | pattern | semmle.label | pattern | -| RegexInjection.java:107:22:107:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:110:42:110:48 | pattern | semmle.label | pattern | -| RegexInjection.java:114:22:114:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:117:44:117:50 | pattern | semmle.label | pattern | -| RegexInjection.java:121:22:121:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:124:41:124:47 | pattern | semmle.label | pattern | -| RegexInjection.java:128:22:128:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:131:43:131:49 | pattern | semmle.label | pattern | -| RegexInjection.java:143:22:143:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| RegexInjection.java:146:45:146:51 | pattern | semmle.label | pattern | -subpaths -| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:71:14:71:23 | str : String | RegexInjection.java:72:12:72:14 | str : String | RegexInjection.java:68:32:68:43 | foo(...) : String | -#select -| RegexInjection.java:16:26:16:47 | ... + ... | RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:13:22:13:52 | getParameter(...) | user-provided value | -| RegexInjection.java:23:24:23:30 | pattern | RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:20:22:20:52 | getParameter(...) | user-provided value | -| RegexInjection.java:30:31:30:37 | pattern | RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:27:22:27:52 | getParameter(...) | user-provided value | -| RegexInjection.java:37:29:37:35 | pattern | RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:34:22:34:52 | getParameter(...) | user-provided value | -| RegexInjection.java:44:34:44:40 | pattern | RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:41:22:41:52 | getParameter(...) | user-provided value | -| RegexInjection.java:54:28:54:34 | pattern | RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:51:22:51:52 | getParameter(...) | user-provided value | -| RegexInjection.java:61:28:61:34 | pattern | RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:58:22:58:52 | getParameter(...) | user-provided value | -| RegexInjection.java:68:26:68:52 | ... + ... | RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:26:68:52 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:65:22:65:52 | getParameter(...) | user-provided value | -| RegexInjection.java:90:26:90:47 | ... + ... | RegexInjection.java:84:22:84:52 | getParameter(...) : String | RegexInjection.java:90:26:90:47 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:84:22:84:52 | getParameter(...) | user-provided value | -| RegexInjection.java:103:40:103:46 | pattern | RegexInjection.java:100:22:100:52 | getParameter(...) : String | RegexInjection.java:103:40:103:46 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:100:22:100:52 | getParameter(...) | user-provided value | -| RegexInjection.java:110:42:110:48 | pattern | RegexInjection.java:107:22:107:52 | getParameter(...) : String | RegexInjection.java:110:42:110:48 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:107:22:107:52 | getParameter(...) | user-provided value | -| RegexInjection.java:117:44:117:50 | pattern | RegexInjection.java:114:22:114:52 | getParameter(...) : String | RegexInjection.java:117:44:117:50 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:114:22:114:52 | getParameter(...) | user-provided value | -| RegexInjection.java:124:41:124:47 | pattern | RegexInjection.java:121:22:121:52 | getParameter(...) : String | RegexInjection.java:124:41:124:47 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:121:22:121:52 | getParameter(...) | user-provided value | -| RegexInjection.java:131:43:131:49 | pattern | RegexInjection.java:128:22:128:52 | getParameter(...) : String | RegexInjection.java:131:43:131:49 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:128:22:128:52 | getParameter(...) | user-provided value | -| RegexInjection.java:146:45:146:51 | pattern | RegexInjection.java:143:22:143:52 | getParameter(...) : String | RegexInjection.java:146:45:146:51 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:143:22:143:52 | getParameter(...) | user-provided value | diff --git a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.qlref b/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.qlref deleted file mode 100644 index dca594b38d2..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-730/RegexInjection.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-730/options b/java/ql/test/experimental/query-tests/security/CWE-730/options deleted file mode 100644 index 73f1b5a3c3e..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-730/options +++ /dev/null @@ -1 +0,0 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-lang3-3.7 \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/PrintAst.expected b/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/PrintAst.expected index 816b559db7f..3f91fe4f141 100644 --- a/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/PrintAst.expected @@ -1,82 +1,21 @@ test.kt: # 0| [CompilationUnit] test # 3| 1: [Interface] A -# 3| 1: [Constructor] A -#-----| 4: (Parameters) -# 3| 0: [Parameter] c1 -# 3| 0: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 1: [Parameter] c2 -# 3| 0: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 0: [TypeAccess] CharSequence -# 3| 2: [Parameter] c3 -# 3| 0: [TypeAccess] Class -# 3| 0: [TypeAccess] String -# 3| 3: [Parameter] c4 -# 3| 0: [TypeAccess] Class[] -# 3| 0: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 5: [BlockStmt] { ... } -# 3| 0: [SuperConstructorInvocationStmt] super(...) -# 3| 1: [BlockStmt] { ... } -# 3| 0: [ExprStmt] ; -# 3| 0: [KtInitializerAssignExpr] ...=... -# 3| 0: [VarAccess] c1 -# 3| 1: [ExprStmt] ; -# 3| 0: [KtInitializerAssignExpr] ...=... -# 3| 0: [VarAccess] c2 -# 3| 2: [ExprStmt] ; -# 3| 0: [KtInitializerAssignExpr] ...=... -# 3| 0: [VarAccess] c3 -# 3| 3: [ExprStmt] ; -# 3| 0: [KtInitializerAssignExpr] ...=... -# 3| 0: [VarAccess] c4 -# 3| 2: [FieldDeclaration] Class c1; -# 3| -1: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 0: [VarAccess] c1 -# 3| 3: [Method] c1 +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 3| 1: [Method] c1 # 3| 3: [TypeAccess] Class # 3| 0: [WildcardTypeAccess] ? ... -# 3| 5: [BlockStmt] { ... } -# 3| 0: [ReturnStmt] return ... -# 3| 0: [VarAccess] this.c1 -# 3| -1: [ThisAccess] this -# 3| 4: [FieldDeclaration] Class c2; -# 3| -1: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 0: [TypeAccess] CharSequence -# 3| 0: [VarAccess] c2 -# 3| 5: [Method] c2 +# 3| 2: [Method] c2 # 3| 3: [TypeAccess] Class # 3| 0: [WildcardTypeAccess] ? ... # 3| 0: [TypeAccess] CharSequence -# 3| 5: [BlockStmt] { ... } -# 3| 0: [ReturnStmt] return ... -# 3| 0: [VarAccess] this.c2 -# 3| -1: [ThisAccess] this -# 3| 6: [FieldDeclaration] Class c3; -# 3| -1: [TypeAccess] Class -# 3| 0: [TypeAccess] String -# 3| 0: [VarAccess] c3 -# 3| 7: [Method] c3 +# 3| 3: [Method] c3 # 3| 3: [TypeAccess] Class # 3| 0: [TypeAccess] String -# 3| 5: [BlockStmt] { ... } -# 3| 0: [ReturnStmt] return ... -# 3| 0: [VarAccess] this.c3 -# 3| -1: [ThisAccess] this -# 3| 8: [FieldDeclaration] Class[] c4; -# 3| -1: [TypeAccess] Class[] -# 3| 0: [TypeAccess] Class -# 3| 0: [WildcardTypeAccess] ? ... -# 3| 0: [VarAccess] c4 -# 3| 9: [Method] c4 +# 3| 4: [Method] c4 # 3| 3: [TypeAccess] Class[] # 3| 0: [TypeAccess] Class # 3| 0: [WildcardTypeAccess] ? ... -# 3| 5: [BlockStmt] { ... } -# 3| 0: [ReturnStmt] return ... -# 3| 0: [VarAccess] this.c4 -# 3| -1: [ThisAccess] this diff --git a/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/test.expected b/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/test.expected index ce28362cbca..0391e2d9b86 100644 --- a/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/test.expected +++ b/java/ql/test/kotlin/library-tests/annotation-accessor-result-type/test.expected @@ -1,35 +1,9 @@ classExprs -| test.kt:3:20:3:36 | ...=... | Class | | test.kt:3:20:3:36 | Class | Class | -| test.kt:3:20:3:36 | Class | Class | -| test.kt:3:20:3:36 | Class | Class | -| test.kt:3:20:3:36 | c1 | Class | -| test.kt:3:20:3:36 | c1 | Class | -| test.kt:3:20:3:36 | this.c1 | Class | -| test.kt:3:39:3:70 | ...=... | Class | | test.kt:3:39:3:70 | Class | Class | -| test.kt:3:39:3:70 | Class | Class | -| test.kt:3:39:3:70 | Class | Class | -| test.kt:3:39:3:70 | c2 | Class | -| test.kt:3:39:3:70 | c2 | Class | -| test.kt:3:39:3:70 | this.c2 | Class | -| test.kt:3:73:3:94 | ...=... | Class | | test.kt:3:73:3:94 | Class | Class | -| test.kt:3:73:3:94 | Class | Class | -| test.kt:3:73:3:94 | Class | Class | -| test.kt:3:73:3:94 | c3 | Class | -| test.kt:3:73:3:94 | c3 | Class | -| test.kt:3:73:3:94 | this.c3 | Class | -| test.kt:3:97:3:120 | ...=... | Class[] | -| test.kt:3:97:3:120 | Class | Class | -| test.kt:3:97:3:120 | Class | Class | | test.kt:3:97:3:120 | Class | Class | | test.kt:3:97:3:120 | Class[] | Class[] | -| test.kt:3:97:3:120 | Class[] | Class[] | -| test.kt:3:97:3:120 | Class[] | Class[] | -| test.kt:3:97:3:120 | c4 | Class[] | -| test.kt:3:97:3:120 | c4 | Class[] | -| test.kt:3:97:3:120 | this.c4 | Class[] | #select | test.kt:3:20:3:36 | c1 | Class | | test.kt:3:39:3:70 | c2 | Class | diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/Annot0j.java b/java/ql/test/kotlin/library-tests/annotation_classes/Annot0j.java new file mode 100644 index 00000000000..acadc19cc97 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/annotation_classes/Annot0j.java @@ -0,0 +1,3 @@ +public @interface Annot0j { + int abc() default 0; +} \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/Annot1j.java b/java/ql/test/kotlin/library-tests/annotation_classes/Annot1j.java new file mode 100644 index 00000000000..b3b1f072eee --- /dev/null +++ b/java/ql/test/kotlin/library-tests/annotation_classes/Annot1j.java @@ -0,0 +1,15 @@ +public @interface Annot1j { + int a() default 2; + + String b() default "ab"; + + Class c() default X.class; + + Y d() default Y.A; + + Y[] e() default { Y.A, Y.B }; + + Annot0j f() default @Annot0j( + abc = 1 + ); +} \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.expected new file mode 100644 index 00000000000..c457b0811dd --- /dev/null +++ b/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.expected @@ -0,0 +1,280 @@ +Annot0j.java: +# 0| [CompilationUnit] Annot0j +# 1| 1: [Interface] Annot0j +# 2| 1: [Method] abc +# 2| 3: [TypeAccess] int +Annot1j.java: +# 0| [CompilationUnit] Annot1j +# 1| 1: [Interface] Annot1j +# 2| 1: [Method] a +# 2| 3: [TypeAccess] int +# 4| 2: [Method] b +# 4| 3: [TypeAccess] String +# 6| 3: [Method] c +# 6| 3: [TypeAccess] Class<> +# 8| 4: [Method] d +# 8| 3: [TypeAccess] Y +# 10| 5: [Method] e +# 10| 3: [ArrayTypeAccess] ...[] +# 10| 0: [TypeAccess] Y +# 12| 6: [Method] f +# 12| 3: [TypeAccess] Annot0j +def.kt: +# 0| [CompilationUnit] def +# 0| 1: [Class] DefKt +# 46| 2: [Method] fn +#-----| 1: (Annotations) +# 45| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +#-----| 2: (Generic Parameters) +# 46| 0: [TypeVariable] T +# 46| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 46| 0: [Parameter] a +#-----| -1: (Annotations) +# 46| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 46| 0: [TypeAccess] Annot0k +# 46| 5: [BlockStmt] { ... } +# 47| 0: [ExprStmt] ; +# 47| 0: [MethodAccess] println(...) +# 47| -1: [TypeAccess] ConsoleKt +# 47| 0: [MethodAccess] a(...) +# 47| -1: [VarAccess] a +# 50| 1: [LocalVariableDeclStmt] var ...; +# 50| 1: [LocalVariableDeclExpr] x +# 50| 0: [IntegerLiteral] 10 +# 53| 3: [FieldDeclaration] int p; +#-----| -2: (Annotations) +# 56| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 53| -1: [TypeAccess] int +# 57| 0: [IntegerLiteral] 5 +# 57| 4: [Method] getP +#-----| 1: (Annotations) +# 54| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 57| 3: [TypeAccess] int +# 57| 5: [BlockStmt] { ... } +# 57| 0: [ReturnStmt] return ... +# 57| 0: [VarAccess] DefKt.p +# 57| -1: [TypeAccess] DefKt +# 57| 5: [Method] setP +#-----| 1: (Annotations) +# 55| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 57| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 57| 0: [Parameter] +# 57| 0: [TypeAccess] int +# 57| 5: [BlockStmt] { ... } +# 57| 0: [ExprStmt] ; +# 57| 0: [AssignExpr] ...=... +# 57| 0: [VarAccess] DefKt.p +# 57| -1: [TypeAccess] DefKt +# 57| 1: [VarAccess] +# 59| 6: [ExtensionMethod] myExtension +# 59| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 59| 0: [Parameter] +#-----| -1: (Annotations) +# 59| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 59| 0: [TypeAccess] String +# 59| 5: [BlockStmt] { ... } +# 5| 2: [Interface] Annot0k +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 0| 2: [Annotation] Target +# 0| 1: [ArrayInit] {...} +# 0| 1: [VarAccess] ElementType.TYPE +# 0| -1: [TypeAccess] ElementType +# 0| 2: [VarAccess] ElementType.FIELD +# 0| -1: [TypeAccess] ElementType +# 0| 3: [VarAccess] ElementType.METHOD +# 0| -1: [TypeAccess] ElementType +# 0| 4: [VarAccess] ElementType.PARAMETER +# 0| -1: [TypeAccess] ElementType +# 0| 5: [VarAccess] ElementType.CONSTRUCTOR +# 0| -1: [TypeAccess] ElementType +# 0| 6: [VarAccess] ElementType.LOCAL_VARIABLE +# 0| -1: [TypeAccess] ElementType +# 0| 7: [VarAccess] ElementType.ANNOTATION_TYPE +# 0| -1: [TypeAccess] ElementType +# 0| 8: [VarAccess] ElementType.TYPE_PARAMETER +# 0| -1: [TypeAccess] ElementType +# 0| 9: [VarAccess] ElementType.TYPE_USE +# 0| -1: [TypeAccess] ElementType +# 5| 3: [Annotation] Target +# 0| 1: [ArrayInit] {...} +# 0| 1: [VarAccess] AnnotationTarget.CLASS +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 2: [VarAccess] AnnotationTarget.ANNOTATION_CLASS +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 3: [VarAccess] AnnotationTarget.TYPE_PARAMETER +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 4: [VarAccess] AnnotationTarget.PROPERTY +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 5: [VarAccess] AnnotationTarget.FIELD +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 6: [VarAccess] AnnotationTarget.LOCAL_VARIABLE +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 7: [VarAccess] AnnotationTarget.VALUE_PARAMETER +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 8: [VarAccess] AnnotationTarget.CONSTRUCTOR +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 9: [VarAccess] AnnotationTarget.FUNCTION +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 10: [VarAccess] AnnotationTarget.PROPERTY_GETTER +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 11: [VarAccess] AnnotationTarget.PROPERTY_SETTER +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 12: [VarAccess] AnnotationTarget.TYPE +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 13: [VarAccess] AnnotationTarget.FILE +# 0| -1: [TypeAccess] AnnotationTarget +# 0| 14: [VarAccess] AnnotationTarget.TYPEALIAS +# 0| -1: [TypeAccess] AnnotationTarget +# 21| 1: [Method] a +#-----| 1: (Annotations) +# 21| 1: [Annotation] JvmName +# 0| 1: [StringLiteral] "a" +# 21| 3: [TypeAccess] int +# 23| 3: [Interface] Annot1k +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 23| 2: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 25| 1: [Method] a +# 25| 3: [TypeAccess] int +# 26| 2: [Method] b +# 26| 3: [TypeAccess] String +# 27| 3: [Method] c +# 27| 3: [TypeAccess] Class +# 27| 0: [WildcardTypeAccess] ? ... +# 28| 4: [Method] d +# 28| 3: [TypeAccess] Y +# 29| 5: [Method] e +# 29| 3: [TypeAccess] Y[] +# 29| 0: [TypeAccess] Y +# 30| 6: [Method] f +# 30| 3: [TypeAccess] Annot0k +# 33| 4: [Class] X +# 33| 1: [Constructor] X +# 33| 5: [BlockStmt] { ... } +# 33| 0: [SuperConstructorInvocationStmt] super(...) +# 33| 1: [BlockStmt] { ... } +# 34| 5: [Class] Y +# 0| 2: [Method] valueOf +# 0| 3: [TypeAccess] Y +#-----| 4: (Parameters) +# 0| 0: [Parameter] value +# 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Y[] +# 0| 0: [TypeAccess] Y +# 34| 4: [Constructor] Y +# 34| 5: [BlockStmt] { ... } +# 34| 0: [ExprStmt] ; +# 34| 0: [ClassInstanceExpr] new Enum(...) +# 34| -3: [TypeAccess] Enum +# 34| 0: [TypeAccess] Y +# 34| 0: [NullLiteral] null +# 34| 1: [IntegerLiteral] 0 +# 34| 1: [BlockStmt] { ... } +# 35| 5: [FieldDeclaration] Y A; +# 35| -1: [TypeAccess] Y +# 35| 0: [ClassInstanceExpr] new Y(...) +# 35| -3: [TypeAccess] Y +# 35| 6: [FieldDeclaration] Y B; +# 35| -1: [TypeAccess] Y +# 35| 0: [ClassInstanceExpr] new Y(...) +# 35| -3: [TypeAccess] Y +# 35| 7: [FieldDeclaration] Y C; +# 35| -1: [TypeAccess] Y +# 35| 0: [ClassInstanceExpr] new Y(...) +# 35| -3: [TypeAccess] Y +# 38| 6: [Class] Z +#-----| -3: (Annotations) +# 38| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 1 +# 39| 2: [Annotation] Annot1k +# 0| 1: [IntegerLiteral] 2 +# 0| 2: [StringLiteral] "ab" +# 0| 3: [TypeLiteral] X.class +# 0| 0: [TypeAccess] X +# 0| 4: [VarAccess] Y.B +# 0| -1: [TypeAccess] Y +# 0| 5: [ArrayInit] {...} +# 0| 1: [VarAccess] Y.C +# 0| -1: [TypeAccess] Y +# 0| 2: [VarAccess] Y.A +# 0| -1: [TypeAccess] Y +# 0| 6: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 1 +# 42| 1: [Constructor] Z +#-----| 1: (Annotations) +# 41| 1: [Annotation] Annot0k +# 0| 1: [IntegerLiteral] 0 +# 41| 5: [BlockStmt] { ... } +# 42| 0: [SuperConstructorInvocationStmt] super(...) +# 42| 1: [BlockStmt] { ... } +use.java: +# 0| [CompilationUnit] use +# 1| 1: [Class] use +#-----| -1: (Base Types) +# 1| 0: [TypeAccess] Annot0k +# 3| 2: [Method] a +#-----| 1: (Annotations) +# 2| 1: [Annotation] Override +# 3| 3: [TypeAccess] int +# 3| 5: [BlockStmt] { ... } +# 3| 0: [ReturnStmt] return ... +# 3| 0: [IntegerLiteral] 1 +# 6| 3: [Method] annotationType +#-----| 1: (Annotations) +# 5| 1: [Annotation] Override +# 6| 3: [TypeAccess] Class +# 6| 0: [WildcardTypeAccess] ? ... +# 6| 0: [TypeAccess] Annotation +# 6| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... +# 7| 0: [NullLiteral] null +# 14| 4: [Class] Z +#-----| -3: (Annotations) +# 10| 1: [Annotation] Annot0j +# 10| 1: [IntegerLiteral] 1 +# 11| 2: [Annotation] Annot1j +# 11| 1: [IntegerLiteral] 1 +# 11| 2: [StringLiteral] "ac" +# 11| 3: [TypeLiteral] X.class +# 11| 0: [TypeAccess] X +# 11| 4: [VarAccess] Y.B +# 11| -1: [TypeAccess] Y +# 11| 5: [ArrayInit] {...} +# 11| 3: [VarAccess] Y.C +# 11| -1: [TypeAccess] Y +# 11| 4: [VarAccess] Y.A +# 11| -1: [TypeAccess] Y +# 11| 6: [Annotation] Annot0j +# 11| 1: [IntegerLiteral] 2 +# 12| 3: [Annotation] Annot0k +# 12| 1: [IntegerLiteral] 1 +# 13| 4: [Annotation] Annot1k +# 13| 1: [IntegerLiteral] 1 +# 13| 2: [StringLiteral] "ac" +# 13| 3: [TypeLiteral] X.class +# 13| 0: [TypeAccess] X +# 13| 4: [VarAccess] Y.B +# 13| -1: [TypeAccess] Y +# 13| 5: [ArrayInit] {...} +# 13| 3: [VarAccess] Y.C +# 13| -1: [TypeAccess] Y +# 13| 4: [VarAccess] Y.A +# 13| -1: [TypeAccess] Y +# 13| 6: [Annotation] Annot0k +# 13| 1: [IntegerLiteral] 2 diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.qlref b/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.qlref new file mode 100644 index 00000000000..c7fd5faf239 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/annotation_classes/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/java/PrintAst.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/classes.expected b/java/ql/test/kotlin/library-tests/annotation_classes/classes.expected index 240c4bb055b..b04dd33d2e7 100644 --- a/java/ql/test/kotlin/library-tests/annotation_classes/classes.expected +++ b/java/ql/test/kotlin/library-tests/annotation_classes/classes.expected @@ -1,2 +1,82 @@ -| def.kt:2:1:2:31 | SomeAnnotation | Interface | -| use.java:2:23:2:25 | use | Class | +annotationDeclarations +| Annot0j.java:1:19:1:25 | Annot0j | Annot0j.java:2:9:2:11 | abc | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:2:9:2:9 | a | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:4:12:4:12 | b | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:6:11:6:11 | c | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:8:7:8:7 | d | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:10:9:10:9 | e | +| Annot1j.java:1:19:1:25 | Annot1j | Annot1j.java:12:13:12:13 | f | +| def.kt:5:1:21:60 | Annot0k | def.kt:21:44:21:59 | a | +| def.kt:23:1:31:1 | Annot1k | def.kt:25:5:25:18 | a | +| def.kt:23:1:31:1 | Annot1k | def.kt:26:5:26:24 | b | +| def.kt:23:1:31:1 | Annot1k | def.kt:27:5:27:31 | c | +| def.kt:23:1:31:1 | Annot1k | def.kt:28:5:28:18 | d | +| def.kt:23:1:31:1 | Annot1k | def.kt:29:5:29:32 | e | +| def.kt:23:1:31:1 | Annot1k | def.kt:30:5:30:31 | f | +annotations +| def.kt:0:0:0:0 | Annot0k | def.kt:39:1:39:40 | Annot1k | def.kt:5:1:21:60 | Annot0k | +| def.kt:23:1:23:8 | Annot0k | def.kt:23:1:31:1 | Annot1k | def.kt:5:1:21:60 | Annot0k | +| def.kt:38:1:38:17 | Annot0k | def.kt:38:1:43:1 | Z | def.kt:5:1:21:60 | Annot0k | +| def.kt:39:1:39:40 | Annot1k | def.kt:38:1:43:1 | Z | def.kt:23:1:31:1 | Annot1k | +| def.kt:41:5:41:12 | Annot0k | def.kt:42:5:42:19 | Z | def.kt:5:1:21:60 | Annot0k | +| def.kt:45:1:45:8 | Annot0k | def.kt:46:1:51:1 | fn | def.kt:5:1:21:60 | Annot0k | +| def.kt:46:21:46:28 | Annot0k | def.kt:46:21:46:39 | a | def.kt:5:1:21:60 | Annot0k | +| def.kt:54:1:54:12 | Annot0k | def.kt:57:1:57:23 | getP | def.kt:5:1:21:60 | Annot0k | +| def.kt:55:1:55:12 | Annot0k | def.kt:57:1:57:23 | setP | def.kt:5:1:21:60 | Annot0k | +| def.kt:56:1:56:14 | Annot0k | def.kt:53:1:57:23 | p | def.kt:5:1:21:60 | Annot0k | +| def.kt:59:5:59:21 | Annot0k | def.kt:59:5:59:28 | | def.kt:5:1:21:60 | Annot0k | +| use.java:10:5:10:21 | Annot0j | use.java:14:18:14:18 | Z | Annot0j.java:1:19:1:25 | Annot0j | +| use.java:11:5:11:90 | Annot1j | use.java:14:18:14:18 | Z | Annot1j.java:1:19:1:25 | Annot1j | +| use.java:11:73:11:89 | Annot0j | use.java:11:5:11:90 | Annot1j | Annot0j.java:1:19:1:25 | Annot0j | +| use.java:12:5:12:19 | Annot0k | use.java:14:18:14:18 | Z | def.kt:5:1:21:60 | Annot0k | +| use.java:13:5:13:88 | Annot1k | use.java:14:18:14:18 | Z | def.kt:23:1:31:1 | Annot1k | +| use.java:13:73:13:87 | Annot0k | use.java:13:5:13:88 | Annot1k | def.kt:5:1:21:60 | Annot0k | +annotationValues +| def.kt:0:0:0:0 | Annot0k | def.kt:0:0:0:0 | 1 | +| def.kt:0:0:0:0 | Retention | def.kt:0:0:0:0 | RetentionPolicy.RUNTIME | +| def.kt:0:0:0:0 | Retention | def.kt:0:0:0:0 | RetentionPolicy.RUNTIME | +| def.kt:0:0:0:0 | Target | def.kt:0:0:0:0 | {...} | +| def.kt:5:1:20:1 | Target | def.kt:0:0:0:0 | {...} | +| def.kt:21:26:21:42 | JvmName | def.kt:0:0:0:0 | "a" | +| def.kt:23:1:23:8 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:38:1:38:17 | Annot0k | def.kt:0:0:0:0 | 1 | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | 2 | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | "ab" | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | Annot0k | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | X.class | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | Y.B | +| def.kt:39:1:39:40 | Annot1k | def.kt:0:0:0:0 | {...} | +| def.kt:41:5:41:12 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:45:1:45:8 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:46:21:46:28 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:54:1:54:12 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:55:1:55:12 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:56:1:56:14 | Annot0k | def.kt:0:0:0:0 | 0 | +| def.kt:59:5:59:21 | Annot0k | def.kt:0:0:0:0 | 0 | +| use.java:10:5:10:21 | Annot0j | use.java:10:20:10:20 | 1 | +| use.java:11:5:11:90 | Annot1j | use.java:11:18:11:18 | 1 | +| use.java:11:5:11:90 | Annot1j | use.java:11:25:11:28 | "ac" | +| use.java:11:5:11:90 | Annot1j | use.java:11:35:11:41 | X.class | +| use.java:11:5:11:90 | Annot1j | use.java:11:48:11:50 | Y.B | +| use.java:11:5:11:90 | Annot1j | use.java:11:57:11:66 | {...} | +| use.java:11:5:11:90 | Annot1j | use.java:11:73:11:89 | Annot0j | +| use.java:11:73:11:89 | Annot0j | use.java:11:88:11:88 | 2 | +| use.java:12:5:12:19 | Annot0k | use.java:12:18:12:18 | 1 | +| use.java:13:5:13:88 | Annot1k | use.java:13:18:13:18 | 1 | +| use.java:13:5:13:88 | Annot1k | use.java:13:25:13:28 | "ac" | +| use.java:13:5:13:88 | Annot1k | use.java:13:35:13:41 | X.class | +| use.java:13:5:13:88 | Annot1k | use.java:13:48:13:50 | Y.B | +| use.java:13:5:13:88 | Annot1k | use.java:13:57:13:66 | {...} | +| use.java:13:5:13:88 | Annot1k | use.java:13:73:13:87 | Annot0k | +| use.java:13:73:13:87 | Annot0k | use.java:13:86:13:86 | 2 | +#select +| Annot0j.java:1:19:1:25 | Annot0j | Interface | +| Annot1j.java:1:19:1:25 | Annot1j | Interface | +| def.kt:0:0:0:0 | DefKt | Class | +| def.kt:5:1:21:60 | Annot0k | Interface | +| def.kt:23:1:31:1 | Annot1k | Interface | +| def.kt:33:1:33:10 | X | Class | +| def.kt:34:1:36:1 | Y | Class | +| def.kt:38:1:43:1 | Z | Class | +| use.java:1:14:1:16 | use | Class | +| use.java:14:18:14:18 | Z | Class | diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/classes.ql b/java/ql/test/kotlin/library-tests/annotation_classes/classes.ql index 652ab21520f..936165cf023 100644 --- a/java/ql/test/kotlin/library-tests/annotation_classes/classes.ql +++ b/java/ql/test/kotlin/library-tests/annotation_classes/classes.ql @@ -3,3 +3,18 @@ import java from ClassOrInterface x where x.fromSource() select x, x.getPrimaryQlClasses() + +query predicate annotationDeclarations(AnnotationType at, AnnotationElement ae) { + at.fromSource() and + at.getAnAnnotationElement() = ae +} + +query predicate annotations(Annotation a, Element e, AnnotationType at) { + at.fromSource() and + a.getAnnotatedElement() = e and + at = a.getType() +} + +query predicate annotationValues(Annotation a, Expr v) { + a.getValue(_) = v and v.getFile().isSourceFile() +} diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/def.kt b/java/ql/test/kotlin/library-tests/annotation_classes/def.kt index 46c2c2055d4..f499d1026fc 100644 --- a/java/ql/test/kotlin/library-tests/annotation_classes/def.kt +++ b/java/ql/test/kotlin/library-tests/annotation_classes/def.kt @@ -1,5 +1,62 @@ +@file:Annot0k -annotation class SomeAnnotation +import kotlin.reflect.KClass -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata +@Target(AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.TYPE_PARAMETER, + AnnotationTarget.PROPERTY, + AnnotationTarget.FIELD, + AnnotationTarget.LOCAL_VARIABLE, // TODO + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.TYPE, // TODO + //AnnotationTarget.EXPRESSION, // TODO + AnnotationTarget.FILE, // TODO + AnnotationTarget.TYPEALIAS // TODO +) +annotation class Annot0k(@get:JvmName("a") val abc: Int = 0) + +@Annot0k +annotation class Annot1k( + val a: Int = 2, + val b: String = "ab", + val c: KClass<*> = X::class, + val d: Y = Y.A, + val e: Array = [Y.A, Y.B], + val f: Annot0k = Annot0k(1) +) + +class X {} +enum class Y { + A,B,C +} + +@Annot0k(abc = 1) +@Annot1k(d = Y.B, e = arrayOf(Y.C, Y.A)) +class Z { + @Annot0k + constructor(){} +} + +@Annot0k +fun <@Annot0k T> fn(@Annot0k a: Annot0k) { + println(a.abc) + + @Annot0k + var x = 10 +} + +@Annot0k +@get:Annot0k +@set:Annot0k +@field:Annot0k +var p: @Annot0k Int = 5 + +fun @receiver:Annot0k String.myExtension() { } + +@Annot0k +typealias AAA = Z diff --git a/java/ql/test/kotlin/library-tests/annotation_classes/use.java b/java/ql/test/kotlin/library-tests/annotation_classes/use.java index b848298e1ff..ec0dd0fa447 100644 --- a/java/ql/test/kotlin/library-tests/annotation_classes/use.java +++ b/java/ql/test/kotlin/library-tests/annotation_classes/use.java @@ -1,3 +1,15 @@ +public class use implements Annot0k { + @Override + public int a() { return 1; } -public abstract class use implements SomeAnnotation {} + @Override + public Class annotationType() { + return null; + } + @Annot0j(abc = 1) + @Annot1j(a = 1, b = "ac", c = X.class, d = Y.B, e = {Y.C, Y.A}, f = @Annot0j(abc = 2)) + @Annot0k(a = 1) + @Annot1k(a = 1, b = "ac", c = X.class, d = Y.B, e = {Y.C, Y.A}, f = @Annot0k(a = 2)) + public class Z { } +} diff --git a/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt b/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt index b4a4bcf38be..eea98625d5c 100644 --- a/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt +++ b/java/ql/test/kotlin/library-tests/annotations/jvmName/test.kt @@ -16,11 +16,3 @@ class X { annotation class Ann( val p: Int, @get:JvmName("w") val q: Int) - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="changeY") -// Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="getX_prop") -// Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="method") -// Diagnostic Matches: Incomplete annotation: @kotlin.jvm.JvmName(name="y") -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Unknown location for kotlin.jvm.JvmName diff --git a/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt b/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt index 7f529df2dc9..1278d866d84 100644 --- a/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt +++ b/java/ql/test/kotlin/library-tests/arrays-with-variances/takesArrayList.kt @@ -110,8 +110,3 @@ public class TakesArrayList { fun inInArrayComparableAny(c: Comparable>>) { } } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull diff --git a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected index 698a4f874c9..6f19fb37fee 100644 --- a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected @@ -138,14 +138,14 @@ classes.kt: # 39| 0: [ExprStmt] ; # 39| 0: [MethodAccess] f(...) # 39| -1: [TypeAccess] ClassesKt -# 39| 0: [StringLiteral] init1 +# 39| 0: [StringLiteral] "init1" # 42| 1: [ExprStmt] ; # 42| 0: [KtInitializerAssignExpr] ...=... # 42| 0: [VarAccess] x # 45| 2: [ExprStmt] ; # 45| 0: [MethodAccess] f(...) # 45| -1: [TypeAccess] ClassesKt -# 45| 0: [StringLiteral] init2 +# 45| 0: [StringLiteral] "init2" # 36| 2: [ExprStmt] ; # 36| 0: [MethodAccess] f(...) # 36| -1: [TypeAccess] ClassesKt @@ -1119,7 +1119,7 @@ local_anonymous.kt: # 40| 1: [BlockStmt] { ... } # 42| 0: [LocalVariableDeclStmt] var ...; # 42| 1: [LocalVariableDeclExpr] answer -# 42| 0: [StringLiteral] 42 +# 42| 0: [StringLiteral] "42" # 40| 1: [ExprStmt] ; # 40| 0: [ClassInstanceExpr] new (...) # 40| -3: [TypeAccess] Interface2 diff --git a/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected b/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected index 99312685a0e..cbcabc82bd5 100644 --- a/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/collection-literals/PrintAst.expected @@ -1,84 +1,12 @@ test.kt: # 0| [CompilationUnit] test # 1| 1: [Interface] Ann -# 1| 1: [Constructor] Ann -#-----| 4: (Parameters) -# 1| 0: [Parameter] arr1 -# 1| 0: [TypeAccess] String[] -# 1| 0: [TypeAccess] String -# 1| 1: [Parameter] arr2 -# 1| 0: [TypeAccess] int[] -# 1| 5: [BlockStmt] { ... } -# 1| 0: [SuperConstructorInvocationStmt] super(...) -# 1| 1: [BlockStmt] { ... } -# 1| 0: [ExprStmt] ; -# 1| 0: [KtInitializerAssignExpr] ...=... -# 1| 0: [VarAccess] arr1 -# 1| 1: [ExprStmt] ; -# 1| 0: [KtInitializerAssignExpr] ...=... -# 1| 0: [VarAccess] arr2 -# 1| 2: [Constructor] Ann -#-----| 4: (Parameters) -# 1| 0: [Parameter] p0 -# 1| 0: [TypeAccess] String[] -# 1| 1: [Parameter] p1 -# 1| 0: [TypeAccess] int[] -# 1| 2: [Parameter] p2 -# 1| 0: [TypeAccess] int -# 1| 3: [Parameter] p3 -# 1| 0: [TypeAccess] DefaultConstructorMarker -# 1| 5: [BlockStmt] { ... } -# 1| 0: [IfStmt] if (...) -# 1| 0: [EQExpr] ... == ... -# 1| 0: [AndBitwiseExpr] ... & ... -# 1| 0: [IntegerLiteral] 1 -# 1| 1: [VarAccess] p2 -# 1| 1: [IntegerLiteral] 0 -# 1| 1: [ExprStmt] ; -# 1| 0: [AssignExpr] ...=... -# 1| 0: [VarAccess] p0 -# 0| 1: [ArrayCreationExpr] new String[] -# 0| -2: [ArrayInit] {...} -# 0| 0: [StringLiteral] hello -# 0| 1: [StringLiteral] world -# 0| -1: [TypeAccess] String -# 0| 0: [IntegerLiteral] 2 -# 1| 1: [IfStmt] if (...) -# 1| 0: [EQExpr] ... == ... -# 1| 0: [AndBitwiseExpr] ... & ... -# 1| 0: [IntegerLiteral] 2 -# 1| 1: [VarAccess] p2 -# 1| 1: [IntegerLiteral] 0 -# 1| 1: [ExprStmt] ; -# 1| 0: [AssignExpr] ...=... -# 1| 0: [VarAccess] p1 -# 0| 1: [ArrayCreationExpr] new int[] -# 0| -2: [ArrayInit] {...} -# 0| 0: [IntegerLiteral] 1 -# 0| 1: [IntegerLiteral] 2 -# 0| 2: [IntegerLiteral] 3 -# 0| -1: [TypeAccess] int -# 0| 0: [IntegerLiteral] 3 -# 1| 2: [ThisConstructorInvocationStmt] this(...) -# 1| 0: [VarAccess] p0 -# 1| 1: [VarAccess] p1 -# 1| 3: [FieldDeclaration] String[] arr1; -# 1| -1: [TypeAccess] String[] -# 1| 0: [TypeAccess] String -# 1| 0: [VarAccess] arr1 -# 1| 4: [Method] arr1 +#-----| -3: (Annotations) +# 0| 1: [Annotation] Retention +# 0| 1: [VarAccess] RetentionPolicy.RUNTIME +# 0| -1: [TypeAccess] RetentionPolicy +# 1| 1: [Method] arr1 # 1| 3: [TypeAccess] String[] # 1| 0: [TypeAccess] String -# 1| 5: [BlockStmt] { ... } -# 1| 0: [ReturnStmt] return ... -# 1| 0: [VarAccess] this.arr1 -# 1| -1: [ThisAccess] this -# 1| 5: [Method] arr2 +# 1| 2: [Method] arr2 # 1| 3: [TypeAccess] int[] -# 1| 5: [BlockStmt] { ... } -# 1| 0: [ReturnStmt] return ... -# 1| 0: [VarAccess] this.arr2 -# 1| -1: [ThisAccess] this -# 1| 6: [FieldDeclaration] int[] arr2; -# 1| -1: [TypeAccess] int[] -# 1| 0: [VarAccess] arr2 diff --git a/java/ql/test/kotlin/library-tests/comments/comments.expected b/java/ql/test/kotlin/library-tests/comments/comments.expected index f37e8322feb..7bd80ec0ed0 100644 --- a/java/ql/test/kotlin/library-tests/comments/comments.expected +++ b/java/ql/test/kotlin/library-tests/comments/comments.expected @@ -25,7 +25,6 @@ commentOwners | comments.kt:19:5:22:7 | /**\n * Adds a [member] to this group.\n * @return the new size of the group.\n */ | comments.kt:23:5:26:5 | add | | comments.kt:35:5:35:34 | /** Medium is in the middle */ | comments.kt:36:5:36:14 | Medium | | comments.kt:37:5:37:23 | /** This is high */ | comments.kt:38:5:38:11 | High | -| comments.kt:42:5:44:7 | /**\n * A variable.\n */ | comments.kt:45:5:45:13 | int a | | comments.kt:48:1:50:3 | /**\n * A type alias comment\n */ | comments.kt:51:1:51:24 | MyType | | comments.kt:54:5:56:7 | /**\n * An init block comment\n */ | comments.kt:53:1:58:1 | InitBlock | | comments.kt:61:5:63:7 | /**\n * A prop comment\n */ | comments.kt:64:5:68:17 | prop | @@ -40,6 +39,7 @@ commentNoOwners | comments.kt:1:1:1:25 | /** Kdoc with no owner */ | | comments.kt:24:9:24:25 | // A line comment | | comments.kt:28:5:30:6 | /*\n A block comment\n */ | +| comments.kt:42:5:44:7 | /**\n * A variable.\n */ | | comments.kt:95:1:95:163 | // Diagnostic Matches: % Couldn't get owner of KDoc. The comment is extracted without an owner. ...while extracting a file (comments.kt) at %comments.kt:1:1:96:0% | commentSections | comments.kt:1:1:1:25 | /** Kdoc with no owner */ | Kdoc with no owner | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected index 4e0724fca1f..767e68d2f75 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStmts.expected @@ -4,18 +4,18 @@ | Test.kt:3:1:80:1 | { ... } | 3 | Test.kt:3:8:80:1 | Test | | Test.kt:4:2:79:2 | test | 0 | Test.kt:4:2:79:2 | test | | Test.kt:4:13:79:2 | { ... } | 0 | Test.kt:4:13:79:2 | { ... } | -| Test.kt:4:13:79:2 | { ... } | 1 | Test.kt:5:3:5:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 1 | Test.kt:5:7:5:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 2 | Test.kt:5:16:5:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 3 | Test.kt:5:3:5:16 | x | -| Test.kt:4:13:79:2 | { ... } | 4 | Test.kt:6:3:6:18 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 3 | Test.kt:5:7:5:7 | x | +| Test.kt:4:13:79:2 | { ... } | 4 | Test.kt:6:7:6:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 5 | Test.kt:6:17:6:18 | 50 | -| Test.kt:4:13:79:2 | { ... } | 6 | Test.kt:6:3:6:18 | y | -| Test.kt:4:13:79:2 | { ... } | 7 | Test.kt:7:3:7:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 6 | Test.kt:6:7:6:7 | y | +| Test.kt:4:13:79:2 | { ... } | 7 | Test.kt:7:7:7:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 8 | Test.kt:7:16:7:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 9 | Test.kt:7:3:7:16 | z | -| Test.kt:4:13:79:2 | { ... } | 10 | Test.kt:8:3:8:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | 9 | Test.kt:7:7:7:7 | z | +| Test.kt:4:13:79:2 | { ... } | 10 | Test.kt:8:7:8:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | 11 | Test.kt:8:16:8:16 | 0 | -| Test.kt:4:13:79:2 | { ... } | 12 | Test.kt:8:3:8:16 | w | +| Test.kt:4:13:79:2 | { ... } | 12 | Test.kt:8:7:8:7 | w | | Test.kt:4:13:79:2 | { ... } | 13 | Test.kt:11:3:16:3 | ; | | Test.kt:4:13:79:2 | { ... } | 14 | Test.kt:11:3:16:3 | when ... | | Test.kt:4:13:79:2 | { ... } | 15 | Test.kt:11:3:16:3 | ... -> ... | @@ -106,12 +106,12 @@ | Test.kt:82:21:89:1 | { ... } | 0 | Test.kt:82:21:89:1 | { ... } | | Test.kt:82:21:89:1 | { ... } | 1 | Test.kt:83:2:88:2 | try ... | | Test.kt:82:21:89:1 | { ... } | 2 | Test.kt:83:6:86:2 | { ... } | -| Test.kt:82:21:89:1 | { ... } | 3 | Test.kt:84:3:84:18 | var ...; | +| Test.kt:82:21:89:1 | { ... } | 3 | Test.kt:84:7:84:7 | var ...; | | Test.kt:82:21:89:1 | { ... } | 4 | Test.kt:84:11:84:11 | o | | Test.kt:82:21:89:1 | { ... } | 5 | Test.kt:84:11:84:18 | (...)... | -| Test.kt:84:3:84:18 | x | 0 | Test.kt:84:3:84:18 | x | -| Test.kt:84:3:84:18 | x | 1 | Test.kt:85:10:85:10 | 1 | -| Test.kt:84:3:84:18 | x | 2 | Test.kt:85:3:85:10 | return ... | +| Test.kt:84:7:84:7 | x | 0 | Test.kt:84:7:84:7 | x | +| Test.kt:84:7:84:7 | x | 1 | Test.kt:85:10:85:10 | 1 | +| Test.kt:84:7:84:7 | x | 2 | Test.kt:85:3:85:10 | return ... | | Test.kt:86:4:88:2 | catch (...) | 0 | Test.kt:86:4:88:2 | catch (...) | | Test.kt:86:4:88:2 | catch (...) | 1 | Test.kt:86:11:86:31 | e | | Test.kt:86:4:88:2 | catch (...) | 2 | Test.kt:86:34:88:2 | { ... } | @@ -121,12 +121,12 @@ | Test.kt:91:22:98:1 | { ... } | 0 | Test.kt:91:22:98:1 | { ... } | | Test.kt:91:22:98:1 | { ... } | 1 | Test.kt:92:2:97:2 | try ... | | Test.kt:91:22:98:1 | { ... } | 2 | Test.kt:92:6:95:2 | { ... } | -| Test.kt:91:22:98:1 | { ... } | 3 | Test.kt:93:3:93:13 | var ...; | +| Test.kt:91:22:98:1 | { ... } | 3 | Test.kt:93:7:93:7 | var ...; | | Test.kt:91:22:98:1 | { ... } | 4 | Test.kt:93:11:93:11 | o | | Test.kt:91:22:98:1 | { ... } | 5 | Test.kt:93:12:93:13 | ...!! | -| Test.kt:93:3:93:13 | x | 0 | Test.kt:93:3:93:13 | x | -| Test.kt:93:3:93:13 | x | 1 | Test.kt:94:10:94:10 | 1 | -| Test.kt:93:3:93:13 | x | 2 | Test.kt:94:3:94:10 | return ... | +| Test.kt:93:7:93:7 | x | 0 | Test.kt:93:7:93:7 | x | +| Test.kt:93:7:93:7 | x | 1 | Test.kt:94:10:94:10 | 1 | +| Test.kt:93:7:93:7 | x | 2 | Test.kt:94:3:94:10 | return ... | | Test.kt:95:4:97:2 | catch (...) | 0 | Test.kt:95:4:97:2 | catch (...) | | Test.kt:95:4:97:2 | catch (...) | 1 | Test.kt:95:11:95:33 | e | | Test.kt:95:4:97:2 | catch (...) | 2 | Test.kt:95:36:97:2 | { ... } | @@ -155,7 +155,7 @@ | Test.kt:105:5:109:5 | ; | 5 | Test.kt:105:9:105:17 | ... (value not-equals) ... | | Test.kt:105:20:107:5 | { ... } | 0 | Test.kt:105:20:107:5 | { ... } | | Test.kt:105:20:107:5 | { ... } | 1 | Test.kt:106:9:106:29 | ; | -| Test.kt:105:20:107:5 | { ... } | 2 | Test.kt:106:18:106:27 | x not null | +| Test.kt:105:20:107:5 | { ... } | 2 | Test.kt:106:18:106:27 | "x not null" | | Test.kt:105:20:107:5 | { ... } | 3 | Test.kt:106:9:106:29 | println(...) | | Test.kt:107:16:109:5 | ... -> ... | 0 | Test.kt:107:16:109:5 | ... -> ... | | Test.kt:107:16:109:5 | ... -> ... | 1 | Test.kt:107:16:107:16 | y | @@ -163,7 +163,7 @@ | Test.kt:107:16:109:5 | ... -> ... | 3 | Test.kt:107:16:107:24 | ... (value not-equals) ... | | Test.kt:107:27:109:5 | { ... } | 0 | Test.kt:107:27:109:5 | { ... } | | Test.kt:107:27:109:5 | { ... } | 1 | Test.kt:108:9:108:29 | ; | -| Test.kt:107:27:109:5 | { ... } | 2 | Test.kt:108:18:108:27 | y not null | +| Test.kt:107:27:109:5 | { ... } | 2 | Test.kt:108:18:108:27 | "y not null" | | Test.kt:107:27:109:5 | { ... } | 3 | Test.kt:108:9:108:29 | println(...) | | Test.kt:112:1:116:1 | fn | 0 | Test.kt:112:1:116:1 | fn | | Test.kt:112:32:116:1 | { ... } | 0 | Test.kt:112:32:116:1 | { ... } | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected index bea96c9445f..90c7d07b8c3 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbStrictDominance.expected @@ -28,10 +28,10 @@ | Test.kt:38:9:38:9 | x | Test.kt:38:16:41:3 | { ... } | | Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | ; | | Test.kt:82:21:89:1 | { ... } | Test.kt:82:1:89:1 | t1 | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | x | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:91:22:98:1 | { ... } | Test.kt:91:1:98:1 | t2 | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | x | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:100:25:110:1 | { ... } | Test.kt:100:1:110:1 | fn | | Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected index 512a6907e2a..35c28b25b91 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/bbSuccessor.expected @@ -13,13 +13,13 @@ | Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | ; | | Test.kt:38:16:41:3 | { ... } | Test.kt:38:9:38:9 | x | | Test.kt:43:3:43:3 | ; | Test.kt:4:2:79:2 | test | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | x | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | -| Test.kt:84:3:84:18 | x | Test.kt:82:1:89:1 | t1 | +| Test.kt:84:7:84:7 | x | Test.kt:82:1:89:1 | t1 | | Test.kt:86:4:88:2 | catch (...) | Test.kt:82:1:89:1 | t1 | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | x | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | -| Test.kt:93:3:93:13 | x | Test.kt:91:1:98:1 | t2 | +| Test.kt:93:7:93:7 | x | Test.kt:91:1:98:1 | t2 | | Test.kt:95:4:97:2 | catch (...) | Test.kt:91:1:98:1 | t2 | | Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y | | Test.kt:100:25:110:1 | { ... } | Test.kt:105:5:109:5 | ; | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected index bba6e9cbae7..36544bd2d93 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/getASuccessor.expected @@ -8,23 +8,23 @@ missingSuccessor | Test.kt:3:8:80:1 | { ... } | BlockStmt | Test.kt:3:8:80:1 | Test | Constructor | | Test.kt:4:2:79:2 | Unit | TypeAccess | file://:0:0:0:0 | | | | Test.kt:4:2:79:2 | test | Method | file://:0:0:0:0 | | | -| Test.kt:4:13:79:2 | { ... } | BlockStmt | Test.kt:5:3:5:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:5:3:5:16 | int x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:5:3:5:16 | var ...; | LocalVariableDeclStmt | Test.kt:5:16:5:16 | 0 | IntegerLiteral | -| Test.kt:5:3:5:16 | x | LocalVariableDeclExpr | Test.kt:6:3:6:18 | var ...; | LocalVariableDeclStmt | -| Test.kt:5:16:5:16 | 0 | IntegerLiteral | Test.kt:5:3:5:16 | x | LocalVariableDeclExpr | -| Test.kt:6:3:6:18 | long y | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:6:3:6:18 | var ...; | LocalVariableDeclStmt | Test.kt:6:17:6:18 | 50 | LongLiteral | -| Test.kt:6:3:6:18 | y | LocalVariableDeclExpr | Test.kt:7:3:7:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:6:17:6:18 | 50 | LongLiteral | Test.kt:6:3:6:18 | y | LocalVariableDeclExpr | -| Test.kt:7:3:7:16 | int z | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:7:3:7:16 | var ...; | LocalVariableDeclStmt | Test.kt:7:16:7:16 | 0 | IntegerLiteral | -| Test.kt:7:3:7:16 | z | LocalVariableDeclExpr | Test.kt:8:3:8:16 | var ...; | LocalVariableDeclStmt | -| Test.kt:7:16:7:16 | 0 | IntegerLiteral | Test.kt:7:3:7:16 | z | LocalVariableDeclExpr | -| Test.kt:8:3:8:16 | int w | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:8:3:8:16 | var ...; | LocalVariableDeclStmt | Test.kt:8:16:8:16 | 0 | IntegerLiteral | -| Test.kt:8:3:8:16 | w | LocalVariableDeclExpr | Test.kt:11:3:16:3 | ; | ExprStmt | -| Test.kt:8:16:8:16 | 0 | IntegerLiteral | Test.kt:8:3:8:16 | w | LocalVariableDeclExpr | +| Test.kt:4:13:79:2 | { ... } | BlockStmt | Test.kt:5:7:5:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:5:7:5:7 | int x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:5:7:5:7 | var ...; | LocalVariableDeclStmt | Test.kt:5:16:5:16 | 0 | IntegerLiteral | +| Test.kt:5:7:5:7 | x | LocalVariableDeclExpr | Test.kt:6:7:6:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:5:16:5:16 | 0 | IntegerLiteral | Test.kt:5:7:5:7 | x | LocalVariableDeclExpr | +| Test.kt:6:7:6:7 | long y | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:6:7:6:7 | var ...; | LocalVariableDeclStmt | Test.kt:6:17:6:18 | 50 | LongLiteral | +| Test.kt:6:7:6:7 | y | LocalVariableDeclExpr | Test.kt:7:7:7:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:6:17:6:18 | 50 | LongLiteral | Test.kt:6:7:6:7 | y | LocalVariableDeclExpr | +| Test.kt:7:7:7:7 | int z | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:7:7:7:7 | var ...; | LocalVariableDeclStmt | Test.kt:7:16:7:16 | 0 | IntegerLiteral | +| Test.kt:7:7:7:7 | z | LocalVariableDeclExpr | Test.kt:8:7:8:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:7:16:7:16 | 0 | IntegerLiteral | Test.kt:7:7:7:7 | z | LocalVariableDeclExpr | +| Test.kt:8:7:8:7 | int w | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:8:7:8:7 | var ...; | LocalVariableDeclStmt | Test.kt:8:16:8:16 | 0 | IntegerLiteral | +| Test.kt:8:7:8:7 | w | LocalVariableDeclExpr | Test.kt:11:3:16:3 | ; | ExprStmt | +| Test.kt:8:16:8:16 | 0 | IntegerLiteral | Test.kt:8:7:8:7 | w | LocalVariableDeclExpr | | Test.kt:11:3:16:3 | ... -> ... | WhenBranch | Test.kt:11:3:16:3 | true | BooleanLiteral | | Test.kt:11:3:16:3 | ... -> ... | WhenBranch | Test.kt:11:7:11:7 | x | VarAccess | | Test.kt:11:3:16:3 | ; | ExprStmt | Test.kt:11:3:16:3 | when ... | WhenExpr | @@ -137,12 +137,12 @@ missingSuccessor | Test.kt:82:8:82:13 | o | Parameter | file://:0:0:0:0 | | | | Test.kt:82:21:89:1 | { ... } | BlockStmt | Test.kt:83:2:88:2 | try ... | TryStmt | | Test.kt:83:2:88:2 | try ... | TryStmt | Test.kt:83:6:86:2 | { ... } | BlockStmt | -| Test.kt:83:6:86:2 | { ... } | BlockStmt | Test.kt:84:3:84:18 | var ...; | LocalVariableDeclStmt | -| Test.kt:84:3:84:18 | int x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:84:3:84:18 | var ...; | LocalVariableDeclStmt | Test.kt:84:11:84:11 | o | VarAccess | -| Test.kt:84:3:84:18 | x | LocalVariableDeclExpr | Test.kt:85:10:85:10 | 1 | IntegerLiteral | +| Test.kt:83:6:86:2 | { ... } | BlockStmt | Test.kt:84:7:84:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:84:7:84:7 | int x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:84:7:84:7 | var ...; | LocalVariableDeclStmt | Test.kt:84:11:84:11 | o | VarAccess | +| Test.kt:84:7:84:7 | x | LocalVariableDeclExpr | Test.kt:85:10:85:10 | 1 | IntegerLiteral | | Test.kt:84:11:84:11 | o | VarAccess | Test.kt:84:11:84:18 | (...)... | CastExpr | -| Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:84:3:84:18 | x | LocalVariableDeclExpr | +| Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:84:7:84:7 | x | LocalVariableDeclExpr | | Test.kt:84:11:84:18 | (...)... | CastExpr | Test.kt:86:4:88:2 | catch (...) | CatchClause | | Test.kt:84:11:84:18 | int | TypeAccess | file://:0:0:0:0 | | | | Test.kt:85:3:85:10 | return ... | ReturnStmt | Test.kt:82:1:89:1 | t1 | Method | @@ -160,12 +160,12 @@ missingSuccessor | Test.kt:91:8:91:14 | o | Parameter | file://:0:0:0:0 | | | | Test.kt:91:22:98:1 | { ... } | BlockStmt | Test.kt:92:2:97:2 | try ... | TryStmt | | Test.kt:92:2:97:2 | try ... | TryStmt | Test.kt:92:6:95:2 | { ... } | BlockStmt | -| Test.kt:92:6:95:2 | { ... } | BlockStmt | Test.kt:93:3:93:13 | var ...; | LocalVariableDeclStmt | -| Test.kt:93:3:93:13 | Object x | LocalVariableDecl | file://:0:0:0:0 | | | -| Test.kt:93:3:93:13 | var ...; | LocalVariableDeclStmt | Test.kt:93:11:93:11 | o | VarAccess | -| Test.kt:93:3:93:13 | x | LocalVariableDeclExpr | Test.kt:94:10:94:10 | 1 | IntegerLiteral | +| Test.kt:92:6:95:2 | { ... } | BlockStmt | Test.kt:93:7:93:7 | var ...; | LocalVariableDeclStmt | +| Test.kt:93:7:93:7 | Object x | LocalVariableDecl | file://:0:0:0:0 | | | +| Test.kt:93:7:93:7 | var ...; | LocalVariableDeclStmt | Test.kt:93:11:93:11 | o | VarAccess | +| Test.kt:93:7:93:7 | x | LocalVariableDeclExpr | Test.kt:94:10:94:10 | 1 | IntegerLiteral | | Test.kt:93:11:93:11 | o | VarAccess | Test.kt:93:12:93:13 | ...!! | NotNullExpr | -| Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:93:3:93:13 | x | LocalVariableDeclExpr | +| Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:93:7:93:7 | x | LocalVariableDeclExpr | | Test.kt:93:12:93:13 | ...!! | NotNullExpr | Test.kt:95:4:97:2 | catch (...) | CatchClause | | Test.kt:94:3:94:10 | return ... | ReturnStmt | Test.kt:91:1:98:1 | t2 | Method | | Test.kt:94:10:94:10 | 1 | IntegerLiteral | Test.kt:94:3:94:10 | return ... | ReturnStmt | @@ -207,20 +207,20 @@ missingSuccessor | Test.kt:105:9:107:5 | ... -> ... | WhenBranch | Test.kt:105:9:105:9 | x | VarAccess | | Test.kt:105:14:105:17 | null | NullLiteral | Test.kt:105:9:105:17 | ... (value not-equals) ... | ValueNEExpr | | Test.kt:105:20:107:5 | { ... } | BlockStmt | Test.kt:106:9:106:29 | ; | ExprStmt | -| Test.kt:106:9:106:29 | ; | ExprStmt | Test.kt:106:18:106:27 | x not null | StringLiteral | +| Test.kt:106:9:106:29 | ; | ExprStmt | Test.kt:106:18:106:27 | "x not null" | StringLiteral | | Test.kt:106:9:106:29 | ConsoleKt | TypeAccess | file://:0:0:0:0 | | | | Test.kt:106:9:106:29 | println(...) | MethodAccess | Test.kt:100:1:110:1 | fn | Method | -| Test.kt:106:18:106:27 | x not null | StringLiteral | Test.kt:106:9:106:29 | println(...) | MethodAccess | +| Test.kt:106:18:106:27 | "x not null" | StringLiteral | Test.kt:106:9:106:29 | println(...) | MethodAccess | | Test.kt:107:16:107:16 | y | VarAccess | Test.kt:107:21:107:24 | null | NullLiteral | | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | Test.kt:100:1:110:1 | fn | Method | | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | Test.kt:107:27:109:5 | { ... } | BlockStmt | | Test.kt:107:16:109:5 | ... -> ... | WhenBranch | Test.kt:107:16:107:16 | y | VarAccess | | Test.kt:107:21:107:24 | null | NullLiteral | Test.kt:107:16:107:24 | ... (value not-equals) ... | ValueNEExpr | | Test.kt:107:27:109:5 | { ... } | BlockStmt | Test.kt:108:9:108:29 | ; | ExprStmt | -| Test.kt:108:9:108:29 | ; | ExprStmt | Test.kt:108:18:108:27 | y not null | StringLiteral | +| Test.kt:108:9:108:29 | ; | ExprStmt | Test.kt:108:18:108:27 | "y not null" | StringLiteral | | Test.kt:108:9:108:29 | ConsoleKt | TypeAccess | file://:0:0:0:0 | | | | Test.kt:108:9:108:29 | println(...) | MethodAccess | Test.kt:100:1:110:1 | fn | Method | -| Test.kt:108:18:108:27 | y not null | StringLiteral | Test.kt:108:9:108:29 | println(...) | MethodAccess | +| Test.kt:108:18:108:27 | "y not null" | StringLiteral | Test.kt:108:9:108:29 | println(...) | MethodAccess | | Test.kt:112:1:116:1 | Unit | TypeAccess | file://:0:0:0:0 | | | | Test.kt:112:1:116:1 | fn | Method | file://:0:0:0:0 | | | | Test.kt:112:8:112:17 | boolean | TypeAccess | file://:0:0:0:0 | | | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected index b48a2016130..e5e94d38421 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/strictDominance.expected @@ -1,10 +1,10 @@ | Test.kt:3:1:80:1 | super(...) | Test.kt:3:8:80:1 | { ... } | | Test.kt:3:1:80:1 | { ... } | Test.kt:3:1:80:1 | super(...) | | Test.kt:3:1:80:1 | { ... } | Test.kt:3:8:80:1 | { ... } | -| Test.kt:4:13:79:2 | { ... } | Test.kt:5:3:5:16 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:6:3:6:18 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:7:3:7:16 | var ...; | -| Test.kt:4:13:79:2 | { ... } | Test.kt:8:3:8:16 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:5:7:5:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:6:7:6:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:7:7:7:7 | var ...; | +| Test.kt:4:13:79:2 | { ... } | Test.kt:8:7:8:7 | var ...; | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ; | @@ -38,144 +38,144 @@ | Test.kt:4:13:79:2 | { ... } | Test.kt:73:3:73:3 | ; | | Test.kt:4:13:79:2 | { ... } | Test.kt:77:3:77:3 | ; | | Test.kt:4:13:79:2 | { ... } | Test.kt:78:3:78:8 | return ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:5:3:5:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:5:3:5:16 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:6:3:6:18 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:6:3:6:18 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:8:3:8:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:7:3:7:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:78:3:78:8 | return ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:3:16:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:11:14:14:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:12:4:12:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:13:4:13:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:14:10:16:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:15:4:15:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:18:3:18:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:21:3:24:9 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:22:4:22:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:24:4:24:9 | return ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:27:3:27:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:3:33:3 | ... -> ... | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:3:33:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:30:15:33:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:31:4:31:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:32:4:32:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:35:3:35:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:38:3:41:3 | while (...) | -| Test.kt:8:3:8:16 | var ...; | Test.kt:38:16:41:3 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:39:4:39:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:4 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:40:4:40:6 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:43:3:43:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:73:3:73:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:77:3:77:3 | ; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:5:7:5:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:5:7:5:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:6:7:6:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:6:7:6:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:8:7:8:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:7:7:7:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:78:3:78:8 | return ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:3:16:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:11:14:14:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:12:4:12:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:13:4:13:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:14:10:16:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:15:4:15:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:18:3:18:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:21:3:24:9 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:22:4:22:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:24:4:24:9 | return ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:27:3:27:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:3:33:3 | ... -> ... | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:3:33:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:30:15:33:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:31:4:31:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:32:4:32:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:35:3:35:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:38:3:41:3 | while (...) | +| Test.kt:8:7:8:7 | var ...; | Test.kt:38:16:41:3 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:39:4:39:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:4 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:40:4:40:6 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:43:3:43:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:73:3:73:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:77:3:77:3 | ; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:78:3:78:8 | return ... | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:14:14:3 | { ... } | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:12:4:12:4 | ; | @@ -440,51 +440,51 @@ | Test.kt:77:3:77:3 | ; | Test.kt:78:3:78:8 | return ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:83:2:88:2 | try ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:83:6:86:2 | { ... } | -| Test.kt:82:21:89:1 | { ... } | Test.kt:84:3:84:18 | var ...; | +| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | var ...; | | Test.kt:82:21:89:1 | { ... } | Test.kt:85:3:85:10 | return ... | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:82:21:89:1 | { ... } | Test.kt:86:34:88:2 | { ... } | | Test.kt:82:21:89:1 | { ... } | Test.kt:87:3:87:10 | return ... | | Test.kt:83:2:88:2 | try ... | Test.kt:83:6:86:2 | { ... } | -| Test.kt:83:2:88:2 | try ... | Test.kt:84:3:84:18 | var ...; | +| Test.kt:83:2:88:2 | try ... | Test.kt:84:7:84:7 | var ...; | | Test.kt:83:2:88:2 | try ... | Test.kt:85:3:85:10 | return ... | | Test.kt:83:2:88:2 | try ... | Test.kt:86:4:88:2 | catch (...) | | Test.kt:83:2:88:2 | try ... | Test.kt:86:34:88:2 | { ... } | | Test.kt:83:2:88:2 | try ... | Test.kt:87:3:87:10 | return ... | -| Test.kt:83:6:86:2 | { ... } | Test.kt:84:3:84:18 | var ...; | +| Test.kt:83:6:86:2 | { ... } | Test.kt:84:7:84:7 | var ...; | | Test.kt:83:6:86:2 | { ... } | Test.kt:85:3:85:10 | return ... | | Test.kt:83:6:86:2 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:83:6:86:2 | { ... } | Test.kt:86:34:88:2 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:87:3:87:10 | return ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:85:3:85:10 | return ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:86:4:88:2 | catch (...) | -| Test.kt:84:3:84:18 | var ...; | Test.kt:86:34:88:2 | { ... } | -| Test.kt:84:3:84:18 | var ...; | Test.kt:87:3:87:10 | return ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:85:3:85:10 | return ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:86:4:88:2 | catch (...) | +| Test.kt:84:7:84:7 | var ...; | Test.kt:86:34:88:2 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:87:3:87:10 | return ... | | Test.kt:86:4:88:2 | catch (...) | Test.kt:86:34:88:2 | { ... } | | Test.kt:86:4:88:2 | catch (...) | Test.kt:87:3:87:10 | return ... | | Test.kt:86:34:88:2 | { ... } | Test.kt:87:3:87:10 | return ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:92:2:97:2 | try ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:92:6:95:2 | { ... } | -| Test.kt:91:22:98:1 | { ... } | Test.kt:93:3:93:13 | var ...; | +| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | var ...; | | Test.kt:91:22:98:1 | { ... } | Test.kt:94:3:94:10 | return ... | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:91:22:98:1 | { ... } | Test.kt:95:36:97:2 | { ... } | | Test.kt:91:22:98:1 | { ... } | Test.kt:96:3:96:10 | return ... | | Test.kt:92:2:97:2 | try ... | Test.kt:92:6:95:2 | { ... } | -| Test.kt:92:2:97:2 | try ... | Test.kt:93:3:93:13 | var ...; | +| Test.kt:92:2:97:2 | try ... | Test.kt:93:7:93:7 | var ...; | | Test.kt:92:2:97:2 | try ... | Test.kt:94:3:94:10 | return ... | | Test.kt:92:2:97:2 | try ... | Test.kt:95:4:97:2 | catch (...) | | Test.kt:92:2:97:2 | try ... | Test.kt:95:36:97:2 | { ... } | | Test.kt:92:2:97:2 | try ... | Test.kt:96:3:96:10 | return ... | -| Test.kt:92:6:95:2 | { ... } | Test.kt:93:3:93:13 | var ...; | +| Test.kt:92:6:95:2 | { ... } | Test.kt:93:7:93:7 | var ...; | | Test.kt:92:6:95:2 | { ... } | Test.kt:94:3:94:10 | return ... | | Test.kt:92:6:95:2 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:92:6:95:2 | { ... } | Test.kt:95:36:97:2 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:96:3:96:10 | return ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:94:3:94:10 | return ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:95:4:97:2 | catch (...) | -| Test.kt:93:3:93:13 | var ...; | Test.kt:95:36:97:2 | { ... } | -| Test.kt:93:3:93:13 | var ...; | Test.kt:96:3:96:10 | return ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:94:3:94:10 | return ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:95:4:97:2 | catch (...) | +| Test.kt:93:7:93:7 | var ...; | Test.kt:95:36:97:2 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:96:3:96:10 | return ... | | Test.kt:95:4:97:2 | catch (...) | Test.kt:95:36:97:2 | { ... } | | Test.kt:95:4:97:2 | catch (...) | Test.kt:96:3:96:10 | return ... | | Test.kt:95:36:97:2 | { ... } | Test.kt:96:3:96:10 | return ... | diff --git a/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected b/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected index c7d67d9959b..6d47a44d581 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/basic/strictPostDominance.expected @@ -1,27 +1,27 @@ | Test.kt:3:1:80:1 | super(...) | Test.kt:3:1:80:1 | { ... } | | Test.kt:3:8:80:1 | { ... } | Test.kt:3:1:80:1 | super(...) | | Test.kt:3:8:80:1 | { ... } | Test.kt:3:1:80:1 | { ... } | -| Test.kt:5:3:5:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:6:3:6:18 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:7:3:7:16 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:7:3:7:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:8:3:8:16 | var ...; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:8:3:8:16 | var ...; | Test.kt:7:3:7:16 | var ...; | +| Test.kt:5:7:5:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:6:7:6:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:7:7:7:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:4:13:79:2 | { ... } | +| Test.kt:8:7:8:7 | var ...; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:8:7:8:7 | var ...; | Test.kt:7:7:7:7 | var ...; | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:4:13:79:2 | { ... } | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:5:3:5:16 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:6:3:6:18 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:7:3:7:16 | var ...; | -| Test.kt:11:3:16:3 | ... -> ... | Test.kt:8:3:8:16 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:5:7:5:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:6:7:6:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:7:7:7:7 | var ...; | +| Test.kt:11:3:16:3 | ... -> ... | Test.kt:8:7:8:7 | var ...; | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | ; | | Test.kt:11:3:16:3 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:11:3:16:3 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:11:3:16:3 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:11:3:16:3 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:12:4:12:4 | ; | Test.kt:11:14:14:3 | { ... } | | Test.kt:13:4:13:4 | ; | Test.kt:11:14:14:3 | { ... } | | Test.kt:13:4:13:4 | ; | Test.kt:12:4:12:4 | ; | @@ -29,10 +29,10 @@ | Test.kt:15:4:15:4 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:15:4:15:4 | ; | Test.kt:14:10:16:3 | { ... } | | Test.kt:18:3:18:3 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:18:3:18:3 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:18:3:18:3 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:18:3:18:3 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:18:3:18:3 | ; | Test.kt:11:3:16:3 | ; | @@ -42,10 +42,10 @@ | Test.kt:18:3:18:3 | ; | Test.kt:14:10:16:3 | { ... } | | Test.kt:18:3:18:3 | ; | Test.kt:15:4:15:4 | ; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:4:13:79:2 | { ... } | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:5:3:5:16 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:6:3:6:18 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:7:3:7:16 | var ...; | -| Test.kt:21:3:24:9 | ... -> ... | Test.kt:8:3:8:16 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:5:7:5:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:6:7:6:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:7:7:7:7 | var ...; | +| Test.kt:21:3:24:9 | ... -> ... | Test.kt:8:7:8:7 | var ...; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:11:3:16:3 | ; | @@ -57,10 +57,10 @@ | Test.kt:21:3:24:9 | ... -> ... | Test.kt:18:3:18:3 | ; | | Test.kt:21:3:24:9 | ... -> ... | Test.kt:21:3:24:9 | ; | | Test.kt:21:3:24:9 | ; | Test.kt:4:13:79:2 | { ... } | -| Test.kt:21:3:24:9 | ; | Test.kt:5:3:5:16 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:6:3:6:18 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:7:3:7:16 | var ...; | -| Test.kt:21:3:24:9 | ; | Test.kt:8:3:8:16 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:5:7:5:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:6:7:6:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:7:7:7:7 | var ...; | +| Test.kt:21:3:24:9 | ; | Test.kt:8:7:8:7 | var ...; | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ... -> ... | | Test.kt:21:3:24:9 | ; | Test.kt:11:3:16:3 | ; | @@ -189,18 +189,18 @@ | Test.kt:83:2:88:2 | try ... | Test.kt:82:21:89:1 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:82:21:89:1 | { ... } | | Test.kt:83:6:86:2 | { ... } | Test.kt:83:2:88:2 | try ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:82:21:89:1 | { ... } | -| Test.kt:84:3:84:18 | var ...; | Test.kt:83:2:88:2 | try ... | -| Test.kt:84:3:84:18 | var ...; | Test.kt:83:6:86:2 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:82:21:89:1 | { ... } | +| Test.kt:84:7:84:7 | var ...; | Test.kt:83:2:88:2 | try ... | +| Test.kt:84:7:84:7 | var ...; | Test.kt:83:6:86:2 | { ... } | | Test.kt:86:34:88:2 | { ... } | Test.kt:86:4:88:2 | catch (...) | | Test.kt:87:3:87:10 | return ... | Test.kt:86:4:88:2 | catch (...) | | Test.kt:87:3:87:10 | return ... | Test.kt:86:34:88:2 | { ... } | | Test.kt:92:2:97:2 | try ... | Test.kt:91:22:98:1 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:91:22:98:1 | { ... } | | Test.kt:92:6:95:2 | { ... } | Test.kt:92:2:97:2 | try ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:91:22:98:1 | { ... } | -| Test.kt:93:3:93:13 | var ...; | Test.kt:92:2:97:2 | try ... | -| Test.kt:93:3:93:13 | var ...; | Test.kt:92:6:95:2 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:91:22:98:1 | { ... } | +| Test.kt:93:7:93:7 | var ...; | Test.kt:92:2:97:2 | try ... | +| Test.kt:93:7:93:7 | var ...; | Test.kt:92:6:95:2 | { ... } | | Test.kt:95:36:97:2 | { ... } | Test.kt:95:4:97:2 | catch (...) | | Test.kt:96:3:96:10 | return ... | Test.kt:95:4:97:2 | catch (...) | | Test.kt:96:3:96:10 | return ... | Test.kt:95:36:97:2 | { ... } | diff --git a/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected b/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected index e08a5248672..b76a7777a0d 100644 --- a/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected +++ b/java/ql/test/kotlin/library-tests/controlflow/dominance/dominator.expected @@ -1,18 +1,18 @@ -| Test.kt:2:43:79:2 | { ... } | Test.kt:3:9:3:18 | var ...; | -| Test.kt:3:9:3:18 | var ...; | Test.kt:3:17:3:18 | px | -| Test.kt:3:9:3:18 | x | Test.kt:4:9:4:18 | var ...; | -| Test.kt:3:17:3:18 | px | Test.kt:3:9:3:18 | x | -| Test.kt:4:9:4:18 | var ...; | Test.kt:4:17:4:18 | pw | -| Test.kt:4:9:4:18 | w | Test.kt:5:9:5:18 | var ...; | -| Test.kt:4:17:4:18 | pw | Test.kt:4:9:4:18 | w | -| Test.kt:5:9:5:18 | var ...; | Test.kt:5:17:5:18 | pz | -| Test.kt:5:9:5:18 | z | Test.kt:7:3:7:12 | var ...; | -| Test.kt:5:17:5:18 | pz | Test.kt:5:9:5:18 | z | -| Test.kt:7:3:7:12 | j | Test.kt:8:3:8:18 | var ...; | -| Test.kt:7:3:7:12 | var ...; | Test.kt:7:3:7:12 | j | -| Test.kt:8:3:8:18 | var ...; | Test.kt:8:17:8:18 | 50 | -| Test.kt:8:3:8:18 | y | Test.kt:11:3:16:3 | ; | -| Test.kt:8:17:8:18 | 50 | Test.kt:8:3:8:18 | y | +| Test.kt:2:43:79:2 | { ... } | Test.kt:3:13:3:13 | var ...; | +| Test.kt:3:13:3:13 | var ...; | Test.kt:3:17:3:18 | px | +| Test.kt:3:13:3:13 | x | Test.kt:4:13:4:13 | var ...; | +| Test.kt:3:17:3:18 | px | Test.kt:3:13:3:13 | x | +| Test.kt:4:13:4:13 | var ...; | Test.kt:4:17:4:18 | pw | +| Test.kt:4:13:4:13 | w | Test.kt:5:13:5:13 | var ...; | +| Test.kt:4:17:4:18 | pw | Test.kt:4:13:4:13 | w | +| Test.kt:5:13:5:13 | var ...; | Test.kt:5:17:5:18 | pz | +| Test.kt:5:13:5:13 | z | Test.kt:7:7:7:7 | var ...; | +| Test.kt:5:17:5:18 | pz | Test.kt:5:13:5:13 | z | +| Test.kt:7:7:7:7 | j | Test.kt:8:7:8:7 | var ...; | +| Test.kt:7:7:7:7 | var ...; | Test.kt:7:7:7:7 | j | +| Test.kt:8:7:8:7 | var ...; | Test.kt:8:17:8:18 | 50 | +| Test.kt:8:7:8:7 | y | Test.kt:11:3:16:3 | ; | +| Test.kt:8:17:8:18 | 50 | Test.kt:8:7:8:7 | y | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:3:16:3 | true | | Test.kt:11:3:16:3 | ... -> ... | Test.kt:11:7:11:7 | x | | Test.kt:11:3:16:3 | ; | Test.kt:11:3:16:3 | when ... | @@ -111,11 +111,11 @@ | Test.kt:77:3:77:8 | ...=... | Test.kt:78:10:78:10 | w | | Test.kt:77:7:77:8 | 40 | Test.kt:77:3:77:8 | ...=... | | Test.kt:78:10:78:10 | w | Test.kt:78:3:78:10 | return ... | -| Test.kt:81:25:98:2 | { ... } | Test.kt:83:3:83:12 | var ...; | -| Test.kt:83:3:83:12 | b | Test.kt:84:3:84:12 | var ...; | -| Test.kt:83:3:83:12 | var ...; | Test.kt:83:3:83:12 | b | -| Test.kt:84:3:84:12 | c | Test.kt:85:3:85:3 | ; | -| Test.kt:84:3:84:12 | var ...; | Test.kt:84:3:84:12 | c | +| Test.kt:81:25:98:2 | { ... } | Test.kt:83:7:83:7 | var ...; | +| Test.kt:83:7:83:7 | b | Test.kt:84:7:84:7 | var ...; | +| Test.kt:83:7:83:7 | var ...; | Test.kt:83:7:83:7 | b | +| Test.kt:84:7:84:7 | c | Test.kt:85:3:85:3 | ; | +| Test.kt:84:7:84:7 | var ...; | Test.kt:84:7:84:7 | c | | Test.kt:85:3:85:3 | ; | Test.kt:85:7:85:7 | 0 | | Test.kt:85:3:85:7 | ...=... | Test.kt:86:3:96:3 | while (...) | | Test.kt:85:7:85:7 | 0 | Test.kt:85:3:85:7 | ...=... | diff --git a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected index d52888544dc..7ea9b169c7c 100644 --- a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected @@ -145,19 +145,19 @@ dc.kt: # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] ProtoMapValue( -# 0| 1: [StringLiteral] bytes= +# 0| 0: [StringLiteral] "ProtoMapValue(" +# 0| 1: [StringLiteral] "bytes=" # 0| 2: [MethodAccess] toString(...) # 0| -1: [TypeAccess] Arrays # 0| 0: [VarAccess] this.bytes # 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] strs= +# 0| 3: [StringLiteral] ", " +# 0| 4: [StringLiteral] "strs=" # 0| 5: [MethodAccess] toString(...) # 0| -1: [TypeAccess] Arrays # 0| 0: [VarAccess] this.strs # 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) +# 0| 6: [StringLiteral] ")" # 1| 8: [Constructor] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes diff --git a/java/ql/test/kotlin/library-tests/dataflow/extensionMethod/test.ql b/java/ql/test/kotlin/library-tests/dataflow/extensionMethod/test.ql index 47f3ce17767..f30061c4f59 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/extensionMethod/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/extensionMethod/test.ql @@ -1,6 +1,5 @@ import java import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.ExternalFlow class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:extension-method" } diff --git a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected index f204c12ebe2..7c7b382a9ad 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected +++ b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.expected @@ -2,7 +2,7 @@ | C1.java:10:44:10:46 | "a" | C1.java:12:17:12:20 | ...[...] | | C1.java:10:44:10:46 | "a" | C1.java:15:20:15:23 | ...[...] | | C1.java:10:44:10:46 | "a" | C1.java:19:20:19:20 | s | -| C2.kt:8:32:8:32 | a | C2.kt:9:14:9:14 | l | -| C2.kt:8:32:8:32 | a | C2.kt:10:14:10:17 | ...[...] | -| C2.kt:8:32:8:32 | a | C2.kt:12:18:12:21 | ...[...] | -| C2.kt:8:32:8:32 | a | C2.kt:15:18:15:18 | s | +| C2.kt:8:32:8:32 | "a" | C2.kt:9:14:9:14 | l | +| C2.kt:8:32:8:32 | "a" | C2.kt:10:14:10:17 | ...[...] | +| C2.kt:8:32:8:32 | "a" | C2.kt:12:18:12:21 | ...[...] | +| C2.kt:8:32:8:32 | "a" | C2.kt:15:18:15:18 | s | diff --git a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.ql b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.ql index c14c0ca83d2..1b0dc06d7b7 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/foreach/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/foreach/test.ql @@ -1,6 +1,5 @@ import java import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.ExternalFlow class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:foreach-array-iterator" } diff --git a/java/ql/test/kotlin/library-tests/dataflow/func/test.ql b/java/ql/test/kotlin/library-tests/dataflow/func/test.ql index 54971bbddbd..d9753998114 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/func/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/func/test.ql @@ -1,6 +1,5 @@ import java import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.ExternalFlow class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:lambdaFlow" } diff --git a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml new file mode 100644 index 00000000000..7e049c5de11 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["", "Uri", False, "getQueryParameter", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql index 1bb9801bc64..36fae98724c 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ql @@ -1,12 +1,5 @@ import java import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.ExternalFlow - -class Step extends SummaryModelCsv { - override predicate row(string row) { - row = ";Uri;false;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual" - } -} class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:notNullExprFlow" } diff --git a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml new file mode 100644 index 00000000000..7e049c5de11 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["", "Uri", False, "getQueryParameter", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql index 1bb9801bc64..36fae98724c 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ql @@ -1,12 +1,5 @@ import java import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.dataflow.ExternalFlow - -class Step extends SummaryModelCsv { - override predicate row(string row) { - row = ";Uri;false;getQueryParameter;;;Argument[-1];ReturnValue;taint;manual" - } -} class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:notNullExprFlow" } diff --git a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected index f821bdadd5b..78bf583ec0d 100644 --- a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected @@ -171,7 +171,7 @@ delegatedProperties.kt: # 7| 0: [ExprStmt] ; # 7| 0: [MethodAccess] println(...) # 7| -1: [TypeAccess] ConsoleKt -# 7| 0: [StringLiteral] init +# 7| 0: [StringLiteral] "init" # 8| 1: [ReturnStmt] return ... # 8| 0: [IntegerLiteral] 5 # 6| -3: [TypeAccess] Function0 @@ -2459,10 +2459,10 @@ exprs.kt: # 123| 0: [CharacterLiteral] x # 124| 106: [LocalVariableDeclStmt] var ...; # 124| 1: [LocalVariableDeclExpr] str -# 124| 0: [StringLiteral] string lit +# 124| 0: [StringLiteral] "string lit" # 125| 107: [LocalVariableDeclStmt] var ...; # 125| 1: [LocalVariableDeclExpr] strWithQuote -# 125| 0: [StringLiteral] string " lit +# 125| 0: [StringLiteral] "string \" lit" # 126| 108: [LocalVariableDeclStmt] var ...; # 126| 1: [LocalVariableDeclExpr] b6 # 126| 0: [InstanceOfExpr] ...instanceof... @@ -2480,34 +2480,34 @@ exprs.kt: # 128| 1: [VarAccess] b7 # 129| 111: [LocalVariableDeclStmt] var ...; # 129| 1: [LocalVariableDeclExpr] str1 -# 129| 0: [StringLiteral] string lit +# 129| 0: [StringLiteral] "string lit" # 130| 112: [LocalVariableDeclStmt] var ...; # 130| 1: [LocalVariableDeclExpr] str2 -# 130| 0: [StringLiteral] string lit +# 130| 0: [StringLiteral] "string lit" # 131| 113: [LocalVariableDeclStmt] var ...; # 131| 1: [LocalVariableDeclExpr] str3 # 131| 0: [NullLiteral] null # 132| 114: [LocalVariableDeclStmt] var ...; # 132| 1: [LocalVariableDeclExpr] str4 # 132| 0: [StringTemplateExpr] "..." -# 132| 0: [StringLiteral] foo +# 132| 0: [StringLiteral] "foo " # 132| 1: [VarAccess] str1 -# 132| 2: [StringLiteral] bar +# 132| 2: [StringLiteral] " bar " # 132| 3: [VarAccess] str2 -# 132| 4: [StringLiteral] baz +# 132| 4: [StringLiteral] " baz" # 133| 115: [LocalVariableDeclStmt] var ...; # 133| 1: [LocalVariableDeclExpr] str5 # 133| 0: [StringTemplateExpr] "..." -# 133| 0: [StringLiteral] foo +# 133| 0: [StringLiteral] "foo " # 133| 1: [AddExpr] ... + ... # 133| 0: [VarAccess] str1 # 133| 1: [VarAccess] str2 -# 133| 2: [StringLiteral] bar +# 133| 2: [StringLiteral] " bar " # 133| 3: [MethodAccess] stringPlus(...) # 133| -1: [TypeAccess] Intrinsics # 133| 0: [VarAccess] str2 # 133| 1: [VarAccess] str1 -# 133| 4: [StringLiteral] baz +# 133| 4: [StringLiteral] " baz" # 134| 116: [LocalVariableDeclStmt] var ...; # 134| 1: [LocalVariableDeclExpr] str6 # 134| 0: [AddExpr] ... + ... @@ -3531,12 +3531,12 @@ exprs.kt: # 215| 1: [LocalVariableDeclExpr] d0 # 215| 0: [MethodAccess] valueOf(...) # 215| -1: [TypeAccess] Color -# 215| 0: [StringLiteral] GREEN +# 215| 0: [StringLiteral] "GREEN" # 216| 8: [LocalVariableDeclStmt] var ...; # 216| 1: [LocalVariableDeclExpr] d1 # 216| 0: [MethodAccess] valueOf(...) # 216| -1: [TypeAccess] Color -# 216| 0: [StringLiteral] GREEN +# 216| 0: [StringLiteral] "GREEN" # 224| 11: [Class] SomeClass1 # 224| 1: [Constructor] SomeClass1 # 224| 5: [BlockStmt] { ... } @@ -4468,7 +4468,7 @@ funcExprs.kt: # 36| 0: [TypeAccess] int # 36| 5: [BlockStmt] { ... } # 36| 0: [ReturnStmt] return ... -# 36| 0: [StringLiteral] +# 36| 0: [StringLiteral] "" # 36| -3: [TypeAccess] FunctionN # 36| 0: [TypeAccess] String # 38| 14: [ExprStmt] ; @@ -5316,7 +5316,7 @@ funcExprs.kt: # 90| 0: [TypeAccess] int # 90| 5: [BlockStmt] { ... } # 90| 0: [ReturnStmt] return ... -# 90| 0: [StringLiteral] +# 90| 0: [StringLiteral] "" # 90| -3: [TypeAccess] FunctionN # 90| 0: [TypeAccess] String # 91| 5: [ExprStmt] ; @@ -5407,7 +5407,7 @@ funcExprs.kt: # 94| 0: [TypeAccess] int # 94| 5: [BlockStmt] { ... } # 94| 0: [ReturnStmt] return ... -# 94| 0: [StringLiteral] +# 94| 0: [StringLiteral] "" # 94| -3: [TypeAccess] Function22 # 94| 0: [TypeAccess] Integer # 94| 1: [TypeAccess] Integer @@ -5599,7 +5599,7 @@ funcExprs.kt: # 70| 0: [TypeAccess] int # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... -# 70| 0: [StringLiteral] +# 70| 0: [StringLiteral] "" # 73| 4: [Class] Class3 # 73| 3: [Constructor] Class3 # 73| 5: [BlockStmt] { ... } @@ -5625,7 +5625,7 @@ funcExprs.kt: # 75| 0: [TypeAccess] Integer # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... -# 75| 0: [StringLiteral] a +# 75| 0: [StringLiteral] "a" # 75| -3: [TypeAccess] Function1>,String> # 75| 0: [TypeAccess] Generic> # 75| 0: [TypeAccess] Generic @@ -6014,7 +6014,7 @@ samConversion.kt: # 7| 0: [ReturnStmt] return ... # 7| 0: [ValueEQExpr] ... (value equals) ... # 7| 0: [ExtensionReceiverAccess] this -# 7| 1: [StringLiteral] +# 7| 1: [StringLiteral] "" # 7| -3: [TypeAccess] Function2 # 7| 0: [TypeAccess] String # 7| 1: [TypeAccess] Integer @@ -7058,7 +7058,7 @@ whenExpr.kt: # 6| 1: [ThrowStmt] throw ... # 6| 0: [ClassInstanceExpr] new Exception(...) # 6| -3: [TypeAccess] Exception -# 6| 0: [StringLiteral] No threes please +# 6| 0: [StringLiteral] "No threes please" # 7| 4: [WhenBranch] ... -> ... # 7| 0: [BooleanLiteral] true # 7| 1: [ExprStmt] ; diff --git a/java/ql/test/kotlin/library-tests/exprs/binop.expected b/java/ql/test/kotlin/library-tests/exprs/binop.expected index 4c08b123a68..f69701028d5 100644 --- a/java/ql/test/kotlin/library-tests/exprs/binop.expected +++ b/java/ql/test/kotlin/library-tests/exprs/binop.expected @@ -127,7 +127,7 @@ | localFunctionCalls.kt:5:25:5:29 | ... + ... | localFunctionCalls.kt:5:25:5:25 | i | localFunctionCalls.kt:5:29:5:29 | x | | samConversion.kt:2:33:2:38 | ... % ... | samConversion.kt:2:33:2:34 | it | samConversion.kt:2:38:2:38 | 2 | | samConversion.kt:2:33:2:43 | ... (value equals) ... | samConversion.kt:2:33:2:38 | ... % ... | samConversion.kt:2:43:2:43 | 0 | -| samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:44:7:45 | | +| samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:44:7:45 | "" | | samConversion.kt:10:18:10:22 | ... % ... | samConversion.kt:10:18:10:18 | j | samConversion.kt:10:22:10:22 | 2 | | samConversion.kt:10:18:10:27 | ... (value equals) ... | samConversion.kt:10:18:10:22 | ... % ... | samConversion.kt:10:27:10:27 | 0 | | samConversion.kt:12:18:12:22 | ... % ... | samConversion.kt:12:18:12:18 | j | samConversion.kt:12:22:12:22 | 2 | diff --git a/java/ql/test/kotlin/library-tests/exprs/exprs.expected b/java/ql/test/kotlin/library-tests/exprs/exprs.expected index 08a9891f64b..5d35293eb22 100644 --- a/java/ql/test/kotlin/library-tests/exprs/exprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/exprs.expected @@ -51,7 +51,7 @@ | delegatedProperties.kt:6:32:9:9 | int | file://:0:0:0:0 | | TypeAccess | | delegatedProperties.kt:7:13:7:27 | ConsoleKt | delegatedProperties.kt:6:32:9:9 | invoke | TypeAccess | | delegatedProperties.kt:7:13:7:27 | println(...) | delegatedProperties.kt:6:32:9:9 | invoke | MethodAccess | -| delegatedProperties.kt:7:22:7:25 | init | delegatedProperties.kt:6:32:9:9 | invoke | StringLiteral | +| delegatedProperties.kt:7:22:7:25 | "init" | delegatedProperties.kt:6:32:9:9 | invoke | StringLiteral | | delegatedProperties.kt:8:13:8:13 | 5 | delegatedProperties.kt:6:32:9:9 | invoke | IntegerLiteral | | delegatedProperties.kt:10:9:10:22 | ConsoleKt | delegatedProperties.kt:5:5:12:5 | fn | TypeAccess | | delegatedProperties.kt:10:9:10:22 | println(...) | delegatedProperties.kt:5:5:12:5 | fn | MethodAccess | @@ -904,484 +904,484 @@ | exprs.kt:8:32:8:41 | double | file://:0:0:0:0 | | TypeAccess | | exprs.kt:9:20:9:28 | float | file://:0:0:0:0 | | TypeAccess | | exprs.kt:9:31:9:39 | float | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:11:5:11:14 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:11:9:11:10 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:11:14:11:14 | 1 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | -| exprs.kt:12:5:12:18 | i2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:12:9:12:10 | i2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:12:14:12:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:12:14:12:18 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:12:18:12:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:13:5:13:18 | i3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:13:9:13:10 | i3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:13:14:13:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:13:14:13:18 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:13:18:13:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:14:5:14:18 | i4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:14:9:14:10 | i4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:14:14:14:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:14:14:14:18 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:14:18:14:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:15:5:15:18 | i5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:15:9:15:10 | i5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:15:14:15:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:15:14:15:18 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:15:18:15:18 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:16:5:16:20 | i6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:16:9:16:10 | i6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:16:14:16:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:16:14:16:20 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr | | exprs.kt:16:20:16:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:17:5:17:20 | i7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:17:9:17:10 | i7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:17:14:17:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:17:14:17:20 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr | | exprs.kt:17:20:17:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:18:5:18:21 | i8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:18:9:18:10 | i8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:18:14:18:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:18:14:18:21 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr | | exprs.kt:18:21:18:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:19:5:19:20 | i9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:19:9:19:10 | i9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:19:14:19:14 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:19:14:19:20 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:19:20:19:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:20:5:20:20 | i10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:20:9:20:11 | i10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:20:15:20:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:20:15:20:20 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:20:20:20:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:21:5:21:21 | i11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:21:9:21:11 | i11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:21:15:21:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:21:15:21:21 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:21:21:21:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:22:5:22:21 | i12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:22:9:22:11 | i12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:22:15:22:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:22:15:22:21 | ~... | exprs.kt:4:1:142:1 | topLevelMethod | BitNotExpr | -| exprs.kt:23:5:23:20 | i13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:23:9:23:11 | i13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:23:15:23:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:23:15:23:20 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:23:20:23:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:24:5:24:20 | i14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:24:9:24:11 | i14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:24:15:24:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:24:15:24:20 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:24:20:24:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:25:5:25:19 | i15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:25:9:25:11 | i15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:25:15:25:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:25:15:25:19 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:25:19:25:19 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:26:5:26:20 | i16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:26:9:26:11 | i16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:26:15:26:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:26:15:26:20 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:26:20:26:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:27:5:27:19 | i17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:27:9:27:11 | i17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:27:15:27:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:27:15:27:19 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:27:19:27:19 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:28:5:28:20 | i18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:28:9:28:11 | i18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:28:15:28:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:28:15:28:20 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:28:20:28:20 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:29:5:29:21 | i19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:29:9:29:11 | i19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:29:15:29:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:29:15:29:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:29:21:29:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:30:5:30:21 | i20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:30:9:30:11 | i20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:30:15:30:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:30:15:30:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:30:21:30:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:31:5:31:25 | i21 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:31:9:31:11 | i21 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:31:15:31:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:31:15:31:25 | contains(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:31:20:31:20 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:31:20:31:25 | rangeTo(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:31:25:31:25 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:32:5:32:26 | i22 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:32:9:32:11 | i22 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:32:15:32:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:32:15:32:26 | !... | exprs.kt:4:1:142:1 | topLevelMethod | LogNotExpr | | exprs.kt:32:15:32:26 | contains(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:32:21:32:21 | x | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:32:21:32:26 | rangeTo(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:32:26:32:26 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:34:5:34:17 | by1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:34:9:34:11 | by1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:34:15:34:17 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:35:5:35:23 | by2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:35:9:35:11 | by2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:35:15:35:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:35:15:35:23 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:35:21:35:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:36:5:36:23 | by3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:36:9:36:11 | by3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:36:15:36:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:36:15:36:23 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:36:21:36:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:37:5:37:23 | by4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:37:9:37:11 | by4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:37:15:37:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:37:15:37:23 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:37:21:37:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:38:5:38:23 | by5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:38:9:38:11 | by5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:38:15:38:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:38:15:38:23 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:38:21:38:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:39:5:39:24 | by6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:39:9:39:11 | by6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:39:15:39:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:39:15:39:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:39:15:39:24 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:39:22:39:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:39:22:39:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:40:5:40:24 | by7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:40:9:40:11 | by7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:40:15:40:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:40:15:40:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:40:15:40:24 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:40:22:40:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:40:22:40:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:41:5:41:23 | by8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:41:9:41:11 | by8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:41:15:41:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:41:15:41:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:41:15:41:23 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:41:21:41:23 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:41:21:41:23 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:42:5:42:24 | by9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:42:9:42:11 | by9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:42:15:42:17 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:42:15:42:17 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:42:15:42:24 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:42:22:42:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:42:22:42:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:43:5:43:24 | by10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:43:9:43:12 | by10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:43:16:43:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:43:16:43:18 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:43:16:43:24 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:43:22:43:24 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:43:22:43:24 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:44:5:44:25 | by11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:44:9:44:12 | by11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:44:16:44:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:44:16:44:18 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:44:16:44:25 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:44:23:44:25 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:44:23:44:25 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | -| exprs.kt:45:5:45:26 | by12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:45:9:45:12 | by12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:45:16:45:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:45:16:45:26 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:45:24:45:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:46:5:46:26 | by13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:46:9:46:12 | by13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:46:16:46:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:46:16:46:26 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:46:24:46:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:47:5:47:25 | by14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:47:9:47:12 | by14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:47:16:47:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:47:16:47:25 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:47:23:47:25 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:48:5:48:26 | by15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:48:9:48:12 | by15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:48:16:48:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:48:16:48:26 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:48:24:48:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:49:5:49:26 | by16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:49:9:49:12 | by16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:49:16:49:18 | byx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:49:16:49:26 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:49:24:49:26 | byy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:51:5:51:16 | s1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:51:9:51:10 | s1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:51:14:51:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:52:5:52:20 | s2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:52:9:52:10 | s2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:52:14:52:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:52:14:52:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:52:19:52:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:53:5:53:20 | s3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:53:9:53:10 | s3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:53:14:53:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:53:14:53:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:53:19:53:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:54:5:54:20 | s4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:54:9:54:10 | s4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:54:14:54:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:54:14:54:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:54:19:54:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:55:5:55:20 | s5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:55:9:55:10 | s5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:55:14:55:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:55:14:55:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:55:19:55:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:56:5:56:21 | s6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:56:9:56:10 | s6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:56:14:56:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:56:14:56:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:56:14:56:21 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:56:20:56:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:56:20:56:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:57:5:57:21 | s7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:57:9:57:10 | s7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:57:14:57:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:57:14:57:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:57:14:57:21 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:57:20:57:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:57:20:57:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:58:5:58:20 | s8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:58:9:58:10 | s8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:58:14:58:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:58:14:58:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:58:14:58:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:58:19:58:20 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:58:19:58:20 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:59:5:59:21 | s9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:59:9:59:10 | s9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:59:14:59:15 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:59:14:59:15 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:59:14:59:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:59:20:59:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:59:20:59:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:60:5:60:21 | s10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:60:9:60:11 | s10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:60:15:60:16 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:60:15:60:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:60:15:60:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:60:20:60:21 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:60:20:60:21 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:61:5:61:22 | s11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:61:9:61:11 | s11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:61:15:61:16 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:61:15:61:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:61:15:61:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:61:21:61:22 | intValue(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:61:21:61:22 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:62:5:62:23 | s12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:62:9:62:11 | s12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:62:15:62:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:62:15:62:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:62:22:62:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:63:5:63:23 | s13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:63:9:63:11 | s13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:63:15:63:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:63:15:63:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:63:22:63:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:64:5:64:22 | s14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:64:9:64:11 | s14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:64:15:64:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:64:15:64:22 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:64:21:64:22 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:65:5:65:23 | s15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:65:9:65:11 | s15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:65:15:65:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:65:15:65:23 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:65:22:65:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:66:5:66:23 | s16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:66:9:66:11 | s16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:66:15:66:16 | sx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:66:15:66:23 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:66:22:66:23 | sy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:68:5:68:16 | l1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:68:9:68:10 | l1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:68:14:68:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:69:5:69:20 | l2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:69:9:69:10 | l2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:69:14:69:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:69:14:69:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:69:19:69:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:70:5:70:20 | l3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:70:9:70:10 | l3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:70:14:70:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:70:14:70:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:70:19:70:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:71:5:71:20 | l4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:71:9:71:10 | l4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:71:14:71:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:71:14:71:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:71:19:71:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:72:5:72:20 | l5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:72:9:72:10 | l5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:72:14:72:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:72:14:72:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:72:19:72:20 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:73:5:73:21 | l6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:73:9:73:10 | l6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:73:14:73:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:73:14:73:21 | ... << ... | exprs.kt:4:1:142:1 | topLevelMethod | LShiftExpr | | exprs.kt:73:21:73:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:74:5:74:21 | l7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:74:9:74:10 | l7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:74:14:74:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:74:14:74:21 | ... >> ... | exprs.kt:4:1:142:1 | topLevelMethod | RShiftExpr | | exprs.kt:74:21:74:21 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:75:5:75:22 | l8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:75:9:75:10 | l8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:75:14:75:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:75:14:75:22 | ... >>> ... | exprs.kt:4:1:142:1 | topLevelMethod | URShiftExpr | | exprs.kt:75:22:75:22 | y | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:76:5:76:22 | l9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:76:9:76:10 | l9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:76:14:76:15 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:76:14:76:22 | ... & ... | exprs.kt:4:1:142:1 | topLevelMethod | AndBitwiseExpr | | exprs.kt:76:21:76:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:77:5:77:22 | l10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:77:9:77:11 | l10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:77:15:77:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:77:15:77:22 | ... \| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrBitwiseExpr | | exprs.kt:77:21:77:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:78:5:78:23 | l11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:78:9:78:11 | l11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:78:15:78:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:78:15:78:23 | ... ^ ... | exprs.kt:4:1:142:1 | topLevelMethod | XorBitwiseExpr | | exprs.kt:78:22:78:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:79:5:79:22 | l12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:79:9:79:11 | l12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:79:15:79:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:79:15:79:22 | ~... | exprs.kt:4:1:142:1 | topLevelMethod | BitNotExpr | -| exprs.kt:80:5:80:22 | l13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:80:9:80:11 | l13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:80:15:80:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:80:15:80:22 | ... (value equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueEQExpr | | exprs.kt:80:21:80:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:81:5:81:22 | l14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:81:9:81:11 | l14 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:81:15:81:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:81:15:81:22 | ... (value not-equals) ... | exprs.kt:4:1:142:1 | topLevelMethod | ValueNEExpr | | exprs.kt:81:21:81:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:82:5:82:21 | l15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:82:9:82:11 | l15 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:82:15:82:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:82:15:82:21 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:82:20:82:21 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:83:5:83:22 | l16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:83:9:83:11 | l16 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:83:15:83:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:83:15:83:22 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:83:21:83:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:84:5:84:21 | l17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:84:9:84:11 | l17 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:84:15:84:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:84:15:84:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:84:20:84:21 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:85:5:85:22 | l18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:85:9:85:11 | l18 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:85:15:85:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:85:15:85:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:85:21:85:22 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:86:5:86:23 | l19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:86:9:86:11 | l19 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:86:15:86:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:86:15:86:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:86:22:86:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:87:5:87:23 | l20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:87:9:87:11 | l20 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:87:15:87:16 | lx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:87:15:87:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:87:22:87:23 | ly | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:89:5:89:16 | d1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:89:9:89:10 | d1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:89:14:89:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:90:5:90:20 | d2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:90:9:90:10 | d2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:90:14:90:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:90:14:90:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:90:19:90:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:91:5:91:20 | d3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:91:9:91:10 | d3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:91:14:91:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:91:14:91:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:91:19:91:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:92:5:92:20 | d4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:92:9:92:10 | d4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:92:14:92:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:92:14:92:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:92:19:92:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:93:5:93:20 | d5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:93:9:93:10 | d5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:93:14:93:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:93:14:93:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:93:19:93:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:94:5:94:21 | d6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:94:9:94:10 | d6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:94:14:94:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:94:14:94:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:94:20:94:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:95:5:95:21 | d7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:95:9:95:10 | d7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:95:14:95:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:95:14:95:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:95:20:95:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:96:5:96:20 | d8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:96:9:96:10 | d8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:96:14:96:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:96:14:96:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:96:19:96:20 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:97:5:97:21 | d9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:97:9:97:10 | d9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:97:14:97:15 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:97:14:97:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:97:20:97:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:98:5:98:21 | d10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:98:9:98:11 | d10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:98:15:98:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:98:15:98:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:98:20:98:21 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:99:5:99:22 | d11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:99:9:99:11 | d11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:99:15:99:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:99:15:99:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:99:21:99:22 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:100:5:100:23 | d12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:100:9:100:11 | d12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:100:15:100:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:100:15:100:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:100:22:100:23 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:101:5:101:23 | d13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:101:9:101:11 | d13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:101:15:101:16 | dx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:101:15:101:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:101:22:101:23 | dy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:103:5:103:16 | f1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:103:9:103:10 | f1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:103:14:103:16 | 1.0 | exprs.kt:4:1:142:1 | topLevelMethod | DoubleLiteral | -| exprs.kt:104:5:104:20 | f2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:104:9:104:10 | f2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:104:14:104:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:104:14:104:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:104:19:104:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:105:5:105:20 | f3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:105:9:105:10 | f3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:105:14:105:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:105:14:105:20 | ... - ... | exprs.kt:4:1:142:1 | topLevelMethod | SubExpr | | exprs.kt:105:19:105:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:106:5:106:20 | f4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:106:9:106:10 | f4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:106:14:106:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:106:14:106:20 | ... / ... | exprs.kt:4:1:142:1 | topLevelMethod | DivExpr | | exprs.kt:106:19:106:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:107:5:107:20 | f5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:107:9:107:10 | f5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:107:14:107:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:107:14:107:20 | ... % ... | exprs.kt:4:1:142:1 | topLevelMethod | RemExpr | | exprs.kt:107:19:107:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:108:5:108:21 | f6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:108:9:108:10 | f6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:108:14:108:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:108:14:108:21 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:108:20:108:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:109:5:109:21 | f7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:109:9:109:10 | f7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:109:14:109:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:109:14:109:21 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:109:20:109:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:110:5:110:20 | f8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:110:9:110:10 | f8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:110:14:110:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:110:14:110:20 | ... < ... | exprs.kt:4:1:142:1 | topLevelMethod | LTExpr | | exprs.kt:110:19:110:20 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:111:5:111:21 | f9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:111:9:111:10 | f9 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:111:14:111:15 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:111:14:111:21 | ... <= ... | exprs.kt:4:1:142:1 | topLevelMethod | LEExpr | | exprs.kt:111:20:111:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:112:5:112:21 | f10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:112:9:112:11 | f10 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:112:15:112:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:112:15:112:21 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | | exprs.kt:112:20:112:21 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:113:5:113:22 | f11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:113:9:113:11 | f11 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:113:15:113:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:113:15:113:22 | ... >= ... | exprs.kt:4:1:142:1 | topLevelMethod | GEExpr | | exprs.kt:113:21:113:22 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:114:5:114:23 | f12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:114:9:114:11 | f12 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:114:15:114:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:114:15:114:23 | ... == ... | exprs.kt:4:1:142:1 | topLevelMethod | EQExpr | | exprs.kt:114:22:114:23 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:115:5:115:23 | f13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:115:9:115:11 | f13 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:115:15:115:16 | fx | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:115:15:115:23 | ... != ... | exprs.kt:4:1:142:1 | topLevelMethod | NEExpr | | exprs.kt:115:22:115:23 | fy | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:117:5:117:17 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:117:9:117:10 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:117:14:117:17 | true | exprs.kt:4:1:142:1 | topLevelMethod | BooleanLiteral | -| exprs.kt:118:5:118:18 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:118:9:118:10 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:118:14:118:18 | false | exprs.kt:4:1:142:1 | topLevelMethod | BooleanLiteral | -| exprs.kt:119:5:119:21 | b3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:119:9:119:10 | b3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:119:14:119:15 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:119:14:119:21 | ... && ... | exprs.kt:4:1:142:1 | topLevelMethod | AndLogicalExpr | | exprs.kt:119:20:119:21 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:120:5:120:21 | b4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:120:9:120:10 | b4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:120:14:120:15 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:120:14:120:21 | ... \|\| ... | exprs.kt:4:1:142:1 | topLevelMethod | OrLogicalExpr | | exprs.kt:120:20:120:21 | b2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:121:5:121:16 | b5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:121:9:121:10 | b5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:121:14:121:16 | !... | exprs.kt:4:1:142:1 | topLevelMethod | LogNotExpr | | exprs.kt:121:15:121:16 | b1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:123:5:123:15 | c | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:123:9:123:9 | c | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:123:13:123:15 | x | exprs.kt:4:1:142:1 | topLevelMethod | CharacterLiteral | -| exprs.kt:124:5:124:26 | str | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:124:16:124:25 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:125:5:125:38 | strWithQuote | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:125:25:125:37 | string " lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:126:5:126:22 | b6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:124:9:124:11 | str | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:124:16:124:25 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:125:9:125:20 | strWithQuote | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:125:25:125:37 | "string \\" lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:126:9:126:10 | b6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:126:14:126:15 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:126:14:126:22 | ...instanceof... | exprs.kt:4:1:142:1 | topLevelMethod | InstanceOfExpr | | exprs.kt:126:14:126:22 | int | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:127:5:127:23 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:127:9:127:10 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:127:14:127:15 | i1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:127:14:127:23 | ... !is ... | exprs.kt:4:1:142:1 | topLevelMethod | NotInstanceOfExpr | | exprs.kt:127:14:127:23 | int | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:128:5:128:26 | b8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:128:9:128:10 | b8 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:128:14:128:15 | b7 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:128:14:128:26 | (...)... | exprs.kt:4:1:142:1 | topLevelMethod | CastExpr | | exprs.kt:128:14:128:26 | boolean | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | -| exprs.kt:129:5:129:35 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:129:25:129:34 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:130:5:130:36 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | -| exprs.kt:130:26:130:35 | string lit | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:131:5:131:28 | str3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:129:9:129:12 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:129:25:129:34 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:130:9:130:12 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:130:26:130:35 | "string lit" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:131:9:131:12 | str3 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:131:25:131:28 | null | exprs.kt:4:1:142:1 | topLevelMethod | NullLiteral | -| exprs.kt:132:5:132:48 | str4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:132:9:132:12 | str4 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:132:24:132:48 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | -| exprs.kt:132:25:132:28 | foo | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:132:25:132:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:30:132:33 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:132:34:132:38 | bar | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:132:34:132:38 | " bar " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:132:40:132:43 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:132:44:132:47 | baz | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:133:5:133:66 | str5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:132:44:132:47 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:9:133:12 | str5 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:133:24:133:66 | "..." | exprs.kt:4:1:142:1 | topLevelMethod | StringTemplateExpr | -| exprs.kt:133:25:133:28 | foo | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:25:133:28 | "foo " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:31:133:34 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:133:31:133:41 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:133:38:133:41 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:133:43:133:47 | bar | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:133:43:133:47 | " bar " | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | | exprs.kt:133:50:133:53 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:133:50:133:60 | Intrinsics | exprs.kt:4:1:142:1 | topLevelMethod | TypeAccess | | exprs.kt:133:50:133:60 | stringPlus(...) | exprs.kt:4:1:142:1 | topLevelMethod | MethodAccess | | exprs.kt:133:57:133:60 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:133:62:133:65 | baz | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | -| exprs.kt:134:5:134:26 | str6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:133:62:133:65 | " baz" | exprs.kt:4:1:142:1 | topLevelMethod | StringLiteral | +| exprs.kt:134:9:134:12 | str6 | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:134:16:134:19 | str1 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:134:16:134:26 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:134:23:134:26 | str2 | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | -| exprs.kt:136:5:136:21 | variable | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | +| exprs.kt:136:9:136:16 | variable | exprs.kt:4:1:142:1 | topLevelMethod | LocalVariableDeclExpr | | exprs.kt:136:20:136:21 | 10 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | | exprs.kt:137:12:137:19 | variable | exprs.kt:4:1:142:1 | topLevelMethod | VarAccess | | exprs.kt:137:12:137:23 | ... > ... | exprs.kt:4:1:142:1 | topLevelMethod | GTExpr | @@ -1400,7 +1400,7 @@ | exprs.kt:141:12:141:20 | ... + ... | exprs.kt:4:1:142:1 | topLevelMethod | AddExpr | | exprs.kt:141:18:141:20 | 456 | exprs.kt:4:1:142:1 | topLevelMethod | IntegerLiteral | | exprs.kt:144:1:146:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:145:5:145:23 | d | exprs.kt:144:1:146:1 | getClass | LocalVariableDeclExpr | +| exprs.kt:145:9:145:9 | d | exprs.kt:144:1:146:1 | getClass | LocalVariableDeclExpr | | exprs.kt:145:13:145:16 | true | exprs.kt:144:1:146:1 | getClass | BooleanLiteral | | exprs.kt:145:13:145:23 | ::class | exprs.kt:144:1:146:1 | getClass | ClassExpr | | exprs.kt:148:9:148:18 | ...=... | exprs.kt:148:1:150:1 | C | KtInitializerAssignExpr | @@ -1422,11 +1422,11 @@ | exprs.kt:157:8:157:8 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | | exprs.kt:157:8:157:21 | ...instanceof... | exprs.kt:156:1:163:1 | typeTests | InstanceOfExpr | | exprs.kt:157:8:157:21 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | -| exprs.kt:158:9:158:29 | x1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:158:13:158:14 | x1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:158:29:158:29 | | exprs.kt:156:1:163:1 | typeTests | ImplicitCastExpr | | exprs.kt:158:29:158:29 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | | exprs.kt:158:29:158:29 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | -| exprs.kt:160:5:160:60 | y1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:160:9:160:10 | y1 | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:160:25:160:60 | true | exprs.kt:156:1:163:1 | typeTests | BooleanLiteral | | exprs.kt:160:25:160:60 | when ... | exprs.kt:156:1:163:1 | typeTests | WhenExpr | | exprs.kt:160:29:160:29 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | @@ -1437,7 +1437,7 @@ | exprs.kt:160:45:160:49 | Subclass1 | exprs.kt:156:1:163:1 | typeTests | TypeAccess | | exprs.kt:160:47:160:47 | x | exprs.kt:156:1:163:1 | typeTests | VarAccess | | exprs.kt:160:58:160:58 | y | exprs.kt:156:1:163:1 | typeTests | VarAccess | -| exprs.kt:161:5:161:13 | q | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | +| exprs.kt:161:9:161:9 | q | exprs.kt:156:1:163:1 | typeTests | LocalVariableDeclExpr | | exprs.kt:161:13:161:13 | 1 | exprs.kt:156:1:163:1 | typeTests | IntegerLiteral | | exprs.kt:162:5:162:48 | true | exprs.kt:156:1:163:1 | typeTests | BooleanLiteral | | exprs.kt:162:5:162:48 | when ... | exprs.kt:156:1:163:1 | typeTests | WhenExpr | @@ -1452,18 +1452,18 @@ | exprs.kt:162:46:162:46 | 3 | exprs.kt:156:1:163:1 | typeTests | IntegerLiteral | | exprs.kt:165:1:172:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:165:9:165:18 | Polygon | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:166:5:166:25 | r | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:166:9:166:9 | r | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:166:13:166:13 | p | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:166:13:166:25 | getBounds(...) | exprs.kt:165:1:172:1 | foo | MethodAccess | | exprs.kt:167:5:171:5 | when ... | exprs.kt:165:1:172:1 | foo | WhenExpr | | exprs.kt:167:8:167:8 | r | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:167:8:167:16 | ... (value not-equals) ... | exprs.kt:165:1:172:1 | foo | ValueNEExpr | | exprs.kt:167:13:167:16 | null | exprs.kt:165:1:172:1 | foo | NullLiteral | -| exprs.kt:168:9:168:29 | r2 | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:168:13:168:14 | r2 | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:168:29:168:29 | | exprs.kt:165:1:172:1 | foo | ImplicitNotNullExpr | | exprs.kt:168:29:168:29 | Rectangle | exprs.kt:165:1:172:1 | foo | TypeAccess | | exprs.kt:168:29:168:29 | r | exprs.kt:165:1:172:1 | foo | VarAccess | -| exprs.kt:169:9:169:30 | height | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | +| exprs.kt:169:13:169:18 | height | exprs.kt:165:1:172:1 | foo | LocalVariableDeclExpr | | exprs.kt:169:22:169:23 | r2 | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:169:25:169:30 | r2.height | exprs.kt:165:1:172:1 | foo | VarAccess | | exprs.kt:170:9:170:10 | r2 | exprs.kt:165:1:172:1 | foo | VarAccess | @@ -1534,10 +1534,10 @@ | exprs.kt:181:5:181:18 | new Color(...) | exprs.kt:0:0:0:0 | | ClassInstanceExpr | | exprs.kt:181:10:181:17 | 255 | exprs.kt:0:0:0:0 | | IntegerLiteral | | exprs.kt:184:1:187:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:185:5:185:31 | south | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | +| exprs.kt:185:9:185:13 | south | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | | exprs.kt:185:27:185:31 | Direction | exprs.kt:184:1:187:1 | enums | TypeAccess | | exprs.kt:185:27:185:31 | Direction.SOUTH | exprs.kt:184:1:187:1 | enums | VarAccess | -| exprs.kt:186:5:186:27 | green | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | +| exprs.kt:186:9:186:13 | green | exprs.kt:184:1:187:1 | enums | LocalVariableDeclExpr | | exprs.kt:186:23:186:27 | Color | exprs.kt:184:1:187:1 | enums | TypeAccess | | exprs.kt:186:23:186:27 | Color.GREEN | exprs.kt:184:1:187:1 | enums | VarAccess | | exprs.kt:192:5:192:14 | ...=... | exprs.kt:191:1:199:1 | Class1 | KtInitializerAssignExpr | @@ -1548,7 +1548,7 @@ | exprs.kt:192:5:192:14 | this.a1 | exprs.kt:192:5:192:14 | getA1 | VarAccess | | exprs.kt:192:14:192:14 | 1 | exprs.kt:191:1:199:1 | Class1 | IntegerLiteral | | exprs.kt:193:13:198:5 | Object | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:194:9:194:18 | a2 | exprs.kt:193:13:198:5 | getObject | LocalVariableDeclExpr | +| exprs.kt:194:13:194:14 | a2 | exprs.kt:193:13:198:5 | getObject | LocalVariableDeclExpr | | exprs.kt:194:18:194:18 | 2 | exprs.kt:193:13:198:5 | getObject | IntegerLiteral | | exprs.kt:195:16:197:9 | | exprs.kt:193:13:198:5 | getObject | StmtExpr | | exprs.kt:195:16:197:9 | Interface1 | exprs.kt:193:13:198:5 | getObject | TypeAccess | @@ -1566,55 +1566,55 @@ | exprs.kt:196:36:196:37 | a2 | exprs.kt:195:16:197:9 | | VarAccess | | exprs.kt:201:1:203:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:201:22:201:28 | Object | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:202:5:202:20 | y | exprs.kt:201:1:203:1 | notNullAssertion | LocalVariableDeclExpr | +| exprs.kt:202:9:202:9 | y | exprs.kt:201:1:203:1 | notNullAssertion | LocalVariableDeclExpr | | exprs.kt:202:18:202:18 | x | exprs.kt:201:1:203:1 | notNullAssertion | VarAccess | | exprs.kt:202:19:202:20 | ...!! | exprs.kt:201:1:203:1 | notNullAssertion | NotNullExpr | | exprs.kt:206:5:217:5 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:206:11:206:18 | Object | file://:0:0:0:0 | | TypeAccess | | exprs.kt:206:21:206:30 | String | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:208:9:208:29 | a | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:208:13:208:13 | a | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:208:17:208:18 | aa | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:208:17:208:29 | String | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:208:17:208:29 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:209:9:209:27 | b0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:209:13:209:14 | b0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:209:19:209:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:209:19:209:27 | Intrinsics | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:209:19:209:27 | stringPlus(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:209:26:209:26 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:210:9:210:23 | b1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:210:13:210:14 | b1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:210:19:210:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:210:19:210:23 | Intrinsics | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:210:19:210:23 | stringPlus(...) | exprs.kt:206:5:217:5 | x | MethodAccess | | exprs.kt:210:23:210:23 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:211:9:211:29 | b2 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:211:13:211:14 | b2 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:211:19:211:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:211:20:211:21 | ...!! | exprs.kt:206:5:217:5 | x | NotNullExpr | | exprs.kt:211:20:211:29 | ... + ... | exprs.kt:206:5:217:5 | x | AddExpr | | exprs.kt:211:28:211:28 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:212:9:212:25 | b3 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:212:13:212:14 | b3 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:212:19:212:19 | s | exprs.kt:206:5:217:5 | x | VarAccess | | exprs.kt:212:19:212:25 | ... + ... | exprs.kt:206:5:217:5 | x | AddExpr | | exprs.kt:212:20:212:21 | ...!! | exprs.kt:206:5:217:5 | x | NotNullExpr | | exprs.kt:212:25:212:25 | 5 | exprs.kt:206:5:217:5 | x | IntegerLiteral | -| exprs.kt:213:9:213:36 | c0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:213:13:213:14 | c0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:213:18:213:36 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:213:18:213:36 | values(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:214:9:214:31 | c1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:214:13:214:14 | c1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:214:24:214:31 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:214:24:214:31 | values(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:215:9:215:44 | d0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:215:13:215:14 | d0 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:215:18:215:44 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:215:18:215:44 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:215:38:215:42 | GREEN | exprs.kt:206:5:217:5 | x | StringLiteral | -| exprs.kt:216:9:216:39 | d1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | +| exprs.kt:215:38:215:42 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | +| exprs.kt:216:13:216:14 | d1 | exprs.kt:206:5:217:5 | x | LocalVariableDeclExpr | | exprs.kt:216:24:216:39 | Color | exprs.kt:206:5:217:5 | x | TypeAccess | | exprs.kt:216:24:216:39 | valueOf(...) | exprs.kt:206:5:217:5 | x | MethodAccess | -| exprs.kt:216:33:216:37 | GREEN | exprs.kt:206:5:217:5 | x | StringLiteral | +| exprs.kt:216:33:216:37 | "GREEN" | exprs.kt:206:5:217:5 | x | StringLiteral | | exprs.kt:220:1:222:1 | Unit | file://:0:0:0:0 | | TypeAccess | | exprs.kt:221:5:221:10 | StandardKt | exprs.kt:220:1:222:1 | todo | TypeAccess | | exprs.kt:221:5:221:10 | TODO(...) | exprs.kt:220:1:222:1 | todo | MethodAccess | | exprs.kt:225:1:227:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:226:5:226:29 | x | exprs.kt:225:1:227:1 | fnClassRef | LocalVariableDeclExpr | +| exprs.kt:226:9:226:9 | x | exprs.kt:225:1:227:1 | fnClassRef | LocalVariableDeclExpr | | exprs.kt:226:13:226:29 | SomeClass1 | exprs.kt:225:1:227:1 | fnClassRef | TypeAccess | | exprs.kt:226:13:226:29 | SomeClass1.class | exprs.kt:225:1:227:1 | fnClassRef | TypeLiteral | | exprs.kt:229:1:250:1 | Unit | file://:0:0:0:0 | | TypeAccess | @@ -1622,83 +1622,83 @@ | exprs.kt:229:42:229:64 | Integer | file://:0:0:0:0 | | TypeAccess | | exprs.kt:229:67:229:88 | String | file://:0:0:0:0 | | TypeAccess | | exprs.kt:229:91:229:114 | String | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:230:3:230:47 | b1 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:230:7:230:8 | b1 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:230:12:230:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:230:12:230:47 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:230:32:230:47 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:231:3:231:48 | b2 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:231:7:231:8 | b2 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:231:12:231:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:231:12:231:48 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:231:32:231:48 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:232:3:232:49 | b3 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:232:7:232:8 | b3 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:232:12:232:28 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:232:12:232:49 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:232:33:232:49 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:233:3:233:43 | b4 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:233:7:233:8 | b4 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:233:12:233:25 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:233:12:233:43 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:233:30:233:43 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:234:3:234:44 | b5 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:234:7:234:8 | b5 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:234:12:234:25 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:234:12:234:44 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:234:30:234:44 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:235:3:235:45 | b6 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:235:7:235:8 | b6 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:235:12:235:26 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:235:12:235:45 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:235:31:235:45 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:236:3:236:47 | b7 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:236:7:236:8 | b7 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:236:12:236:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:236:12:236:47 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:236:32:236:47 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:237:3:237:48 | b8 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:237:7:237:8 | b8 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:237:12:237:27 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:237:12:237:48 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:237:32:237:48 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:238:3:238:49 | b9 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:238:7:238:8 | b9 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:238:12:238:28 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:238:12:238:49 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:238:33:238:49 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:239:3:239:44 | b10 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:239:7:239:9 | b10 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:239:13:239:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:239:13:239:44 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:239:31:239:44 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:240:3:240:45 | b11 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:240:7:240:9 | b11 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:240:13:240:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:240:13:240:45 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:240:31:240:45 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:241:3:241:46 | b12 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:241:7:241:9 | b12 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:241:13:241:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:241:13:241:46 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:241:32:241:46 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | -| exprs.kt:242:3:242:36 | b13 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:242:7:242:9 | b13 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:242:13:242:28 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:242:13:242:36 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:242:33:242:36 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:243:3:243:37 | b14 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:243:7:243:9 | b14 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:243:13:243:29 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:243:13:243:37 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:243:34:243:37 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:244:3:244:34 | b15 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:244:7:244:9 | b15 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:244:13:244:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:244:13:244:34 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:244:31:244:34 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:245:3:245:35 | b16 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:245:7:245:9 | b16 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:245:13:245:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:245:13:245:35 | ... (value equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueEQExpr | | exprs.kt:245:32:245:35 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:246:3:246:36 | b17 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:246:7:246:9 | b17 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:246:13:246:28 | notNullPrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:246:13:246:36 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:246:33:246:36 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:247:3:247:37 | b18 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:247:7:247:9 | b18 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:247:13:247:29 | nullablePrimitive | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:247:13:247:37 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:247:34:247:37 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:248:3:248:34 | b19 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:248:7:248:9 | b19 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:248:13:248:26 | notNullReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:248:13:248:34 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:248:31:248:34 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | -| exprs.kt:249:3:249:35 | b20 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | +| exprs.kt:249:7:249:9 | b20 | exprs.kt:229:1:250:1 | equalityTests | LocalVariableDeclExpr | | exprs.kt:249:13:249:27 | nullableReftype | exprs.kt:229:1:250:1 | equalityTests | VarAccess | | exprs.kt:249:13:249:35 | ... (value not-equals) ... | exprs.kt:229:1:250:1 | equalityTests | ValueNEExpr | | exprs.kt:249:32:249:35 | null | exprs.kt:229:1:250:1 | equalityTests | NullLiteral | @@ -1715,28 +1715,28 @@ | exprs.kt:256:30:256:39 | double | file://:0:0:0:0 | | TypeAccess | | exprs.kt:257:18:257:26 | float | file://:0:0:0:0 | | TypeAccess | | exprs.kt:257:29:257:37 | float | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:259:3:259:15 | i | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:259:7:259:7 | i | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:259:11:259:11 | x | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:259:11:259:15 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:259:15:259:15 | y | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:260:3:260:19 | b | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:260:7:260:7 | b | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:260:11:260:13 | byx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:260:11:260:19 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:260:17:260:19 | byy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:261:3:261:17 | l | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:261:7:261:7 | l | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:261:11:261:12 | lx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:261:11:261:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:261:16:261:17 | ly | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:262:3:262:17 | d | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:262:7:262:7 | d | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:262:11:262:12 | dx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:262:11:262:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:262:16:262:17 | dy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | -| exprs.kt:263:3:263:17 | f | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | +| exprs.kt:263:7:263:7 | f | exprs.kt:252:1:265:1 | mulOperators | LocalVariableDeclExpr | | exprs.kt:263:11:263:12 | fx | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:263:11:263:17 | ... * ... | exprs.kt:252:1:265:1 | mulOperators | MulExpr | | exprs.kt:263:16:263:17 | fy | exprs.kt:252:1:265:1 | mulOperators | VarAccess | | exprs.kt:267:1:276:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:269:3:269:17 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | LocalVariableDeclExpr | +| exprs.kt:269:7:269:13 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | LocalVariableDeclExpr | | exprs.kt:269:17:269:17 | 0 | exprs.kt:267:1:276:1 | inPlaceOperators | IntegerLiteral | | exprs.kt:270:3:270:9 | updated | exprs.kt:267:1:276:1 | inPlaceOperators | VarAccess | | exprs.kt:270:3:270:14 | ...+=... | exprs.kt:267:1:276:1 | inPlaceOperators | AssignAddExpr | @@ -1789,9 +1789,9 @@ | exprs.kt:289:5:289:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:289:5:289:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:289:6:289:6 | d | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:290:5:290:14 | i0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:290:9:290:10 | i0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:290:14:290:14 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:291:5:291:14 | i1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:291:9:291:10 | i1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:291:14:291:14 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:292:5:292:6 | i0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:292:5:292:6 | i0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1857,9 +1857,9 @@ | exprs.kt:303:5:303:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:303:5:303:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:303:6:303:6 | b | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:304:5:304:20 | b0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:304:9:304:10 | b0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:304:20:304:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:305:5:305:20 | b1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:305:9:305:10 | b1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:305:20:305:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:306:5:306:6 | b0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:306:5:306:6 | b0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1925,9 +1925,9 @@ | exprs.kt:317:5:317:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:317:5:317:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:317:6:317:6 | s | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:318:5:318:21 | s0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:318:9:318:10 | s0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:318:21:318:21 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | -| exprs.kt:319:5:319:21 | s1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:319:9:319:10 | s1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:319:21:319:21 | 1 | exprs.kt:285:1:346:1 | unaryExprs | IntegerLiteral | | exprs.kt:320:5:320:6 | s0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:320:5:320:6 | s0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -1993,9 +1993,9 @@ | exprs.kt:331:5:331:6 | | exprs.kt:285:1:346:1 | unaryExprs | ImplicitCoercionToUnitExpr | | exprs.kt:331:5:331:6 | Unit | exprs.kt:285:1:346:1 | unaryExprs | TypeAccess | | exprs.kt:331:6:331:6 | l | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | -| exprs.kt:332:5:332:20 | l0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:332:9:332:10 | l0 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:332:20:332:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | LongLiteral | -| exprs.kt:333:5:333:20 | l1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | +| exprs.kt:333:9:333:10 | l1 | exprs.kt:285:1:346:1 | unaryExprs | LocalVariableDeclExpr | | exprs.kt:333:20:333:20 | 1 | exprs.kt:285:1:346:1 | unaryExprs | LongLiteral | | exprs.kt:334:5:334:6 | l0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | | exprs.kt:334:5:334:6 | l0 | exprs.kt:285:1:346:1 | unaryExprs | VarAccess | @@ -2730,7 +2730,7 @@ | funcExprs.kt:36:100:36:102 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:36:104:36:106 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:36:108:36:110 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:36:115:36:116 | | funcExprs.kt:36:29:36:117 | invoke | StringLiteral | +| funcExprs.kt:36:115:36:116 | "" | funcExprs.kt:36:29:36:117 | invoke | StringLiteral | | funcExprs.kt:38:5:38:39 | FuncExprsKt | funcExprs.kt:21:1:52:1 | call | TypeAccess | | funcExprs.kt:38:5:38:39 | functionExpression0a(...) | funcExprs.kt:21:1:52:1 | call | MethodAccess | | funcExprs.kt:38:26:38:34 | FuncRef | funcExprs.kt:21:1:52:1 | call | TypeAccess | @@ -3231,7 +3231,7 @@ | funcExprs.kt:70:102:70:109 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:70:112:70:119 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:70:122:70:129 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:70:134:70:135 | | funcExprs.kt:69:5:70:135 | f23 | StringLiteral | +| funcExprs.kt:70:134:70:135 | "" | funcExprs.kt:69:5:70:135 | f23 | StringLiteral | | funcExprs.kt:74:5:76:5 | Unit | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:9:75:22 | fn(...) | funcExprs.kt:74:5:76:5 | call | MethodAccess | | funcExprs.kt:75:9:75:22 | this | funcExprs.kt:74:5:76:5 | call | ThisAccess | @@ -3245,7 +3245,7 @@ | funcExprs.kt:75:14:75:14 | Generic> | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:14:75:14 | Generic | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:75:14:75:14 | Integer | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:75:20:75:20 | a | funcExprs.kt:75:12:75:22 | invoke | StringLiteral | +| funcExprs.kt:75:20:75:20 | "a" | funcExprs.kt:75:12:75:22 | invoke | StringLiteral | | funcExprs.kt:77:13:77:60 | Unit | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:77:20:77:55 | ? ... | file://:0:0:0:0 | | WildcardTypeAccess | | funcExprs.kt:77:20:77:55 | Function1>,String> | file://:0:0:0:0 | | TypeAccess | @@ -3254,7 +3254,7 @@ | funcExprs.kt:77:20:77:55 | Integer | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:77:20:77:55 | String | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:82:9:96:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:83:5:83:51 | l1 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:83:9:83:10 | l1 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:83:31:83:51 | Function1 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:83:31:83:51 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3268,7 +3268,7 @@ | funcExprs.kt:84:8:84:16 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | | funcExprs.kt:84:8:84:16 | Unit | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:84:15:84:15 | 5 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:86:5:86:59 | l2 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:86:9:86:10 | l2 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:86:39:86:59 | Function1 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:86:39:86:59 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3282,7 +3282,7 @@ | funcExprs.kt:87:8:87:16 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | | funcExprs.kt:87:8:87:16 | Unit | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:87:15:87:15 | 5 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:89:5:90:69 | l3 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:89:9:89:10 | l3 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:90:15:90:69 | 0 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | | funcExprs.kt:90:15:90:69 | 1 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | | funcExprs.kt:90:15:90:69 | 2 | funcExprs.kt:90:15:90:69 | invoke | IntegerLiteral | @@ -3427,7 +3427,7 @@ | funcExprs.kt:90:57:90:57 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:90:59:90:59 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:90:61:90:61 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:90:67:90:68 | | funcExprs.kt:90:15:90:69 | invoke | StringLiteral | +| funcExprs.kt:90:67:90:68 | "" | funcExprs.kt:90:15:90:69 | invoke | StringLiteral | | funcExprs.kt:91:5:91:6 | l3 | funcExprs.kt:82:9:96:1 | fn | VarAccess | | funcExprs.kt:91:5:91:60 | 23 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:5:91:60 | Object | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3459,7 +3459,7 @@ | funcExprs.kt:91:55:91:55 | 1 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:57:91:57 | 2 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | | funcExprs.kt:91:59:91:59 | 3 | funcExprs.kt:82:9:96:1 | fn | IntegerLiteral | -| funcExprs.kt:93:5:94:67 | l4 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | +| funcExprs.kt:93:9:93:10 | l4 | funcExprs.kt:82:9:96:1 | fn | LocalVariableDeclExpr | | funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:82:9:96:1 | fn | LambdaExpr | | funcExprs.kt:94:15:94:67 | Function22 | funcExprs.kt:82:9:96:1 | fn | TypeAccess | | funcExprs.kt:94:15:94:67 | Integer | funcExprs.kt:82:9:96:1 | fn | TypeAccess | @@ -3508,7 +3508,7 @@ | funcExprs.kt:94:55:94:55 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:94:57:94:57 | int | file://:0:0:0:0 | | TypeAccess | | funcExprs.kt:94:59:94:59 | int | file://:0:0:0:0 | | TypeAccess | -| funcExprs.kt:94:65:94:66 | | funcExprs.kt:94:15:94:67 | invoke | StringLiteral | +| funcExprs.kt:94:65:94:66 | "" | funcExprs.kt:94:15:94:67 | invoke | StringLiteral | | funcExprs.kt:95:5:95:6 | l4 | funcExprs.kt:82:9:96:1 | fn | VarAccess | | funcExprs.kt:95:5:95:58 | invoke(...) | funcExprs.kt:82:9:96:1 | fn | MethodAccess | | funcExprs.kt:95:8:95:58 | | funcExprs.kt:82:9:96:1 | fn | ImplicitCoercionToUnitExpr | @@ -3540,7 +3540,7 @@ | kFunctionInvoke.kt:7:1:10:1 | Unit | file://:0:0:0:0 | | TypeAccess | | kFunctionInvoke.kt:7:12:7:15 | A | file://:0:0:0:0 | | TypeAccess | | kFunctionInvoke.kt:7:18:7:26 | String | file://:0:0:0:0 | | TypeAccess | -| kFunctionInvoke.kt:8:5:8:47 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | LocalVariableDeclExpr | +| kFunctionInvoke.kt:8:9:8:14 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | LocalVariableDeclExpr | | kFunctionInvoke.kt:8:44:8:44 | a | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess | | kFunctionInvoke.kt:8:44:8:47 | 1 | kFunctionInvoke.kt:8:44:8:47 | | IntegerLiteral | | kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:7:1:10:1 | useRef | MemberRefExpr | @@ -3560,7 +3560,7 @@ | kFunctionInvoke.kt:9:5:9:13 | invoke(...) | kFunctionInvoke.kt:7:1:10:1 | useRef | MethodAccess | | kFunctionInvoke.kt:9:12:9:12 | s | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess | | localFunctionCalls.kt:3:1:12:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| localFunctionCalls.kt:4:5:4:13 | x | localFunctionCalls.kt:3:1:12:1 | x | LocalVariableDeclExpr | +| localFunctionCalls.kt:4:9:4:9 | x | localFunctionCalls.kt:3:1:12:1 | x | LocalVariableDeclExpr | | localFunctionCalls.kt:4:13:4:13 | 5 | localFunctionCalls.kt:3:1:12:1 | x | IntegerLiteral | | localFunctionCalls.kt:5:5:5:29 | int | file://:0:0:0:0 | | TypeAccess | | localFunctionCalls.kt:5:15:5:20 | int | file://:0:0:0:0 | | TypeAccess | @@ -3607,7 +3607,7 @@ | localFunctionCalls.kt:11:18:11:19 | 42 | localFunctionCalls.kt:3:1:12:1 | x | IntegerLiteral | | samConversion.kt:1:1:14:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:1:10:1:19 | boolean | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:2:5:2:45 | isEven | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:2:9:2:14 | isEven | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:2:18:2:45 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:2:18:2:45 | ...=... | samConversion.kt:2:18:2:45 | | AssignExpr | | samConversion.kt:2:18:2:45 | | samConversion.kt:2:18:2:45 | | VarAccess | @@ -3635,7 +3635,7 @@ | samConversion.kt:2:33:2:43 | ... (value equals) ... | samConversion.kt:2:31:2:45 | invoke | ValueEQExpr | | samConversion.kt:2:38:2:38 | 2 | samConversion.kt:2:31:2:45 | invoke | IntegerLiteral | | samConversion.kt:2:43:2:43 | 0 | samConversion.kt:2:31:2:45 | invoke | IntegerLiteral | -| samConversion.kt:4:5:4:42 | i0 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:4:9:4:10 | i0 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:4:14:4:42 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:4:14:4:42 | ...=... | samConversion.kt:4:14:4:42 | | AssignExpr | | samConversion.kt:4:14:4:42 | | samConversion.kt:4:14:4:42 | | VarAccess | @@ -3664,7 +3664,7 @@ | samConversion.kt:4:29:4:29 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:4:32:4:32 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:4:37:4:40 | INSTANCE | samConversion.kt:4:27:4:42 | invoke | VarAccess | -| samConversion.kt:5:5:5:32 | i1 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:5:9:5:10 | i1 | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:5:14:5:32 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:5:14:5:32 | ...=... | samConversion.kt:5:14:5:32 | | AssignExpr | | samConversion.kt:5:14:5:32 | | samConversion.kt:5:14:5:32 | | VarAccess | @@ -3694,7 +3694,7 @@ | samConversion.kt:5:27:5:31 | a0 | samConversion.kt:5:27:5:31 | invoke | VarAccess | | samConversion.kt:5:27:5:31 | a1 | samConversion.kt:5:27:5:31 | invoke | VarAccess | | samConversion.kt:5:27:5:31 | fn2(...) | samConversion.kt:5:27:5:31 | invoke | MethodAccess | -| samConversion.kt:7:5:7:46 | i | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:7:9:7:9 | i | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:7:13:7:46 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:7:13:7:46 | ...=... | samConversion.kt:7:13:7:46 | | AssignExpr | | samConversion.kt:7:13:7:46 | | samConversion.kt:7:13:7:46 | | VarAccess | @@ -3724,8 +3724,8 @@ | samConversion.kt:7:31:7:31 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:7:36:7:39 | this | samConversion.kt:7:29:7:46 | invoke | ExtensionReceiverAccess | | samConversion.kt:7:36:7:45 | ... (value equals) ... | samConversion.kt:7:29:7:46 | invoke | ValueEQExpr | -| samConversion.kt:7:44:7:45 | | samConversion.kt:7:29:7:46 | invoke | StringLiteral | -| samConversion.kt:9:5:13:6 | x | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | +| samConversion.kt:7:44:7:45 | "" | samConversion.kt:7:29:7:46 | invoke | StringLiteral | +| samConversion.kt:9:9:9:9 | x | samConversion.kt:1:1:14:1 | main | LocalVariableDeclExpr | | samConversion.kt:9:13:13:6 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr | | samConversion.kt:9:13:13:6 | ...=... | samConversion.kt:9:13:13:6 | | AssignExpr | | samConversion.kt:9:13:13:6 | | samConversion.kt:9:13:13:6 | | VarAccess | @@ -3829,7 +3829,7 @@ | samConversion.kt:38:49:38:52 | true | samConversion.kt:36:1:38:52 | ff | BooleanLiteral | | samConversion.kt:40:1:47:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:40:8:40:19 | boolean | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:41:5:41:16 | a | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:41:9:41:9 | a | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:41:13:41:16 | 0 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | | samConversion.kt:41:13:41:16 | 1 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | | samConversion.kt:41:13:41:16 | 2 | samConversion.kt:41:13:41:16 | invoke | IntegerLiteral | @@ -3951,7 +3951,7 @@ | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | | samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess | -| samConversion.kt:42:5:42:32 | b | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:42:9:42:9 | b | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:42:13:42:32 | 23 | samConversion.kt:42:13:42:32 | accept | IntegerLiteral | | samConversion.kt:42:13:42:32 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:42:13:42:32 | ...=... | samConversion.kt:42:13:42:32 | | AssignExpr | @@ -4016,7 +4016,7 @@ | samConversion.kt:42:13:42:32 | this. | samConversion.kt:42:13:42:32 | | VarAccess | | samConversion.kt:42:13:42:32 | {...} | samConversion.kt:42:13:42:32 | accept | ArrayInit | | samConversion.kt:42:31:42:31 | a | samConversion.kt:40:1:47:1 | fn | VarAccess | -| samConversion.kt:43:5:45:68 | c | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:43:9:43:9 | c | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:43:13:45:68 | 23 | samConversion.kt:43:13:45:68 | accept | IntegerLiteral | | samConversion.kt:43:13:45:68 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:43:13:45:68 | ...=... | samConversion.kt:43:13:45:68 | | AssignExpr | @@ -4225,7 +4225,7 @@ | samConversion.kt:45:42:45:49 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:45:52:45:59 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:45:64:45:67 | true | samConversion.kt:43:31:45:68 | invoke | BooleanLiteral | -| samConversion.kt:46:5:46:44 | d | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | +| samConversion.kt:46:9:46:9 | d | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr | | samConversion.kt:46:13:46:44 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr | | samConversion.kt:46:13:46:44 | ...=... | samConversion.kt:46:13:46:44 | | AssignExpr | | samConversion.kt:46:13:46:44 | | samConversion.kt:46:13:46:44 | | VarAccess | @@ -4257,7 +4257,7 @@ | samConversion.kt:54:21:54:26 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:54:29:54:34 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:57:9:60:1 | Unit | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:58:5:58:45 | i0 | samConversion.kt:57:9:60:1 | test | LocalVariableDeclExpr | +| samConversion.kt:58:9:58:10 | i0 | samConversion.kt:57:9:60:1 | test | LocalVariableDeclExpr | | samConversion.kt:58:14:58:45 | (...)... | samConversion.kt:57:9:60:1 | test | CastExpr | | samConversion.kt:58:14:58:45 | ...=... | samConversion.kt:58:14:58:45 | | AssignExpr | | samConversion.kt:58:14:58:45 | | samConversion.kt:58:14:58:45 | | VarAccess | @@ -4302,7 +4302,7 @@ | samConversion.kt:71:5:71:16 | int | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:74:1:77:1 | Unit | file://:0:0:0:0 | | TypeAccess | | samConversion.kt:74:22:74:42 | PropertyRefsTest | file://:0:0:0:0 | | TypeAccess | -| samConversion.kt:75:5:75:33 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | +| samConversion.kt:75:9:75:13 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | | samConversion.kt:75:17:75:33 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr | | samConversion.kt:75:17:75:33 | ...=... | samConversion.kt:75:17:75:33 | | AssignExpr | | samConversion.kt:75:17:75:33 | | samConversion.kt:75:17:75:33 | | VarAccess | @@ -4330,7 +4330,7 @@ | samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | invoke | ThisAccess | | samConversion.kt:75:27:75:32 | this. | samConversion.kt:75:27:75:32 | | VarAccess | | samConversion.kt:75:27:75:32 | this. | samConversion.kt:75:27:75:32 | get | VarAccess | -| samConversion.kt:76:5:76:55 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | +| samConversion.kt:76:9:76:13 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr | | samConversion.kt:76:17:76:55 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr | | samConversion.kt:76:17:76:55 | ...=... | samConversion.kt:76:17:76:55 | | AssignExpr | | samConversion.kt:76:17:76:55 | | samConversion.kt:76:17:76:55 | | VarAccess | @@ -4379,6 +4379,6 @@ | whenExpr.kt:6:5:6:5 | tmp0_subject | whenExpr.kt:1:1:9:1 | testWhen | VarAccess | | whenExpr.kt:6:16:6:44 | Exception | whenExpr.kt:1:1:9:1 | testWhen | TypeAccess | | whenExpr.kt:6:16:6:44 | new Exception(...) | whenExpr.kt:1:1:9:1 | testWhen | ClassInstanceExpr | -| whenExpr.kt:6:27:6:42 | No threes please | whenExpr.kt:1:1:9:1 | testWhen | StringLiteral | +| whenExpr.kt:6:27:6:42 | "No threes please" | whenExpr.kt:1:1:9:1 | testWhen | StringLiteral | | whenExpr.kt:7:13:7:15 | 999 | whenExpr.kt:1:1:9:1 | testWhen | IntegerLiteral | | whenExpr.kt:7:13:7:15 | true | whenExpr.kt:1:1:9:1 | testWhen | BooleanLiteral | diff --git a/java/ql/test/kotlin/library-tests/exprs/exprs.ql b/java/ql/test/kotlin/library-tests/exprs/exprs.ql index 89eb09fc368..b39528a55e4 100644 --- a/java/ql/test/kotlin/library-tests/exprs/exprs.ql +++ b/java/ql/test/kotlin/library-tests/exprs/exprs.ql @@ -35,4 +35,5 @@ MaybeElement enclosingCallable(Expr e) { } from Expr e +where e.getFile().isSourceFile() select e, enclosingCallable(e), e.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected index 81ea4c51841..b79725a80e3 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected @@ -43,41 +43,41 @@ memberRefExprs | samConversion.kt:5:27:5:31 | ...::... | samConversion.kt:5:27:5:31 | invoke | invoke(int,int) | samConversion.kt:5:27:5:31 | new Function2(...) { ... } | | samConversion.kt:41:13:41:16 | ...::... | samConversion.kt:41:13:41:16 | invoke | invoke(java.lang.Object[]) | samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | lambda_modifiers -| delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | override, public | -| funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | override, public | -| funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | override, public | -| funcExprs.kt:24:26:24:33 | ...->... | funcExprs.kt:24:26:24:33 | invoke | override, public | -| funcExprs.kt:25:29:25:38 | ...->... | funcExprs.kt:25:29:25:38 | invoke | override, public | -| funcExprs.kt:26:29:26:34 | ...->... | funcExprs.kt:26:29:26:34 | invoke | override, public | -| funcExprs.kt:27:29:27:42 | ...->... | funcExprs.kt:27:29:27:42 | invoke | override, public | -| funcExprs.kt:29:29:29:37 | ...->... | funcExprs.kt:29:29:29:37 | invoke | override, public | -| funcExprs.kt:30:28:30:50 | ...->... | funcExprs.kt:30:28:30:50 | invoke | override, public | -| funcExprs.kt:31:28:31:40 | ...->... | funcExprs.kt:31:28:31:40 | invoke | override, public | -| funcExprs.kt:32:28:32:44 | ...->... | funcExprs.kt:32:28:32:44 | invoke | override, public | -| funcExprs.kt:33:28:33:51 | ...->... | funcExprs.kt:33:28:33:51 | invoke | override, public | -| funcExprs.kt:33:37:33:47 | ...->... | funcExprs.kt:33:37:33:47 | invoke | override, public | -| funcExprs.kt:35:29:35:112 | ...->... | funcExprs.kt:35:29:35:112 | invoke | override, public | +| delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | final, override, public | +| funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | final, override, public | +| funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | final, override, public | +| funcExprs.kt:24:26:24:33 | ...->... | funcExprs.kt:24:26:24:33 | invoke | final, override, public | +| funcExprs.kt:25:29:25:38 | ...->... | funcExprs.kt:25:29:25:38 | invoke | final, override, public | +| funcExprs.kt:26:29:26:34 | ...->... | funcExprs.kt:26:29:26:34 | invoke | final, override, public | +| funcExprs.kt:27:29:27:42 | ...->... | funcExprs.kt:27:29:27:42 | invoke | final, override, public | +| funcExprs.kt:29:29:29:37 | ...->... | funcExprs.kt:29:29:29:37 | invoke | final, override, public | +| funcExprs.kt:30:28:30:50 | ...->... | funcExprs.kt:30:28:30:50 | invoke | final, override, public | +| funcExprs.kt:31:28:31:40 | ...->... | funcExprs.kt:31:28:31:40 | invoke | final, override, public | +| funcExprs.kt:32:28:32:44 | ...->... | funcExprs.kt:32:28:32:44 | invoke | final, override, public | +| funcExprs.kt:33:28:33:51 | ...->... | funcExprs.kt:33:28:33:51 | invoke | final, override, public | +| funcExprs.kt:33:37:33:47 | ...->... | funcExprs.kt:33:37:33:47 | invoke | final, override, public | +| funcExprs.kt:35:29:35:112 | ...->... | funcExprs.kt:35:29:35:112 | invoke | final, override, public | +| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | final, public | | funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | override, public | -| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | public | -| funcExprs.kt:75:12:75:22 | ...->... | funcExprs.kt:75:12:75:22 | invoke | override, public | -| funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:83:31:83:51 | invoke | override, public | -| funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend | +| funcExprs.kt:75:12:75:22 | ...->... | funcExprs.kt:75:12:75:22 | invoke | final, override, public | +| funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:83:31:83:51 | invoke | final, override, public | +| funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:86:39:86:59 | invoke | final, override, public, suspend | +| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | final, public | | funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | override, public | -| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | public | -| funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend | -| samConversion.kt:2:31:2:45 | ...->... | samConversion.kt:2:31:2:45 | invoke | override, public | -| samConversion.kt:4:27:4:42 | ...->... | samConversion.kt:4:27:4:42 | invoke | override, public | -| samConversion.kt:7:29:7:46 | ...->... | samConversion.kt:7:29:7:46 | invoke | override, public | -| samConversion.kt:9:33:11:5 | ...->... | samConversion.kt:9:33:11:5 | invoke | override, public | -| samConversion.kt:11:12:13:5 | ...->... | samConversion.kt:11:12:13:5 | invoke | override, public | +| funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:94:15:94:67 | invoke | final, override, public, suspend | +| samConversion.kt:2:31:2:45 | ...->... | samConversion.kt:2:31:2:45 | invoke | final, override, public | +| samConversion.kt:4:27:4:42 | ...->... | samConversion.kt:4:27:4:42 | invoke | final, override, public | +| samConversion.kt:7:29:7:46 | ...->... | samConversion.kt:7:29:7:46 | invoke | final, override, public | +| samConversion.kt:9:33:11:5 | ...->... | samConversion.kt:9:33:11:5 | invoke | final, override, public | +| samConversion.kt:11:12:13:5 | ...->... | samConversion.kt:11:12:13:5 | invoke | final, override, public | +| samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | final, public | | samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | override, public | -| samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | public | -| samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | override, public | -| samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | +| samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | final, override, public | +| samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | final, override, public, suspend | anon_class_member_modifiers | delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | get | override, public | | delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | invoke | override, public | -| delegatedProperties.kt:6:32:9:9 | new Function0(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | override, public | +| delegatedProperties.kt:6:32:9:9 | new Function0(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | final, override, public | | delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | | delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | | delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public | @@ -86,8 +86,8 @@ anon_class_member_modifiers | delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public | | delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | get | override, public | | delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | invoke | override, public | -| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | public | -| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | final, public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | final, public | | delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:27:22:27:88 | getValue | override, public | | delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:28:22:30:13 | setValue | override, public | | delegatedProperties.kt:33:27:33:47 | new KProperty0(...) { ... } | delegatedProperties.kt:33:27:33:47 | get | override, public | @@ -187,22 +187,22 @@ anon_class_member_modifiers | delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | get | override, public | | delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | invoke | override, public | | delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | set | override, public | -| exprs.kt:195:16:197:9 | new Interface1(...) { ... } | exprs.kt:196:13:196:49 | getA3 | public | -| funcExprs.kt:22:26:22:33 | new Function0(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | override, public | -| funcExprs.kt:23:26:23:33 | new Function0(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | override, public | -| funcExprs.kt:24:26:24:33 | new Function0(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | override, public | -| funcExprs.kt:25:29:25:38 | new Function1(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | override, public | -| funcExprs.kt:26:29:26:34 | new Function1(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | override, public | -| funcExprs.kt:27:29:27:42 | new Function1(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | override, public | -| funcExprs.kt:29:29:29:37 | new Function1(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | override, public | -| funcExprs.kt:30:28:30:50 | new Function2(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | override, public | -| funcExprs.kt:31:28:31:40 | new Function2(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | override, public | -| funcExprs.kt:32:28:32:44 | new Function2(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | override, public | -| funcExprs.kt:33:28:33:51 | new Function1>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | override, public | -| funcExprs.kt:33:37:33:47 | new Function1(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | override, public | -| funcExprs.kt:35:29:35:112 | new Function22(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | override, public | +| exprs.kt:195:16:197:9 | new Interface1(...) { ... } | exprs.kt:196:13:196:49 | getA3 | final, public | +| funcExprs.kt:22:26:22:33 | new Function0(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | final, override, public | +| funcExprs.kt:23:26:23:33 | new Function0(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | final, override, public | +| funcExprs.kt:24:26:24:33 | new Function0(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | final, override, public | +| funcExprs.kt:25:29:25:38 | new Function1(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | final, override, public | +| funcExprs.kt:26:29:26:34 | new Function1(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | final, override, public | +| funcExprs.kt:27:29:27:42 | new Function1(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | final, override, public | +| funcExprs.kt:29:29:29:37 | new Function1(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | final, override, public | +| funcExprs.kt:30:28:30:50 | new Function2(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | final, override, public | +| funcExprs.kt:31:28:31:40 | new Function2(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | final, override, public | +| funcExprs.kt:32:28:32:44 | new Function2(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | final, override, public | +| funcExprs.kt:33:28:33:51 | new Function1>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | final, override, public | +| funcExprs.kt:33:37:33:47 | new Function1(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | final, override, public | +| funcExprs.kt:35:29:35:112 | new Function22(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | final, override, public | +| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | final, public | | funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | override, public | -| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | public | | funcExprs.kt:38:26:38:38 | new Function0(...) { ... } | funcExprs.kt:38:26:38:38 | invoke | override, public | | funcExprs.kt:39:26:39:36 | new Function0(...) { ... } | funcExprs.kt:39:26:39:36 | invoke | override, public | | funcExprs.kt:40:29:40:41 | new Function1(...) { ... } | funcExprs.kt:40:29:40:41 | invoke | override, public | @@ -214,37 +214,37 @@ anon_class_member_modifiers | funcExprs.kt:46:30:46:41 | new FunctionN(...) { ... } | funcExprs.kt:46:30:46:41 | invoke | override, public | | funcExprs.kt:49:26:49:32 | new Function0(...) { ... } | funcExprs.kt:49:26:49:32 | invoke | override, public | | funcExprs.kt:51:8:51:16 | new Function0(...) { ... } | funcExprs.kt:51:8:51:16 | invoke | override, public | -| funcExprs.kt:75:12:75:22 | new Function1>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | override, public | -| funcExprs.kt:83:31:83:51 | new Function1(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | override, public | -| funcExprs.kt:86:39:86:59 | new Function1(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend | +| funcExprs.kt:75:12:75:22 | new Function1>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | final, override, public | +| funcExprs.kt:83:31:83:51 | new Function1(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | final, override, public | +| funcExprs.kt:86:39:86:59 | new Function1(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | final, override, public, suspend | +| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | final, public | | funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | override, public | -| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | public | -| funcExprs.kt:94:15:94:67 | new Function22(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend | +| funcExprs.kt:94:15:94:67 | new Function22(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | final, override, public, suspend | | kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | kFunctionInvoke.kt:8:44:8:47 | invoke | override, public | -| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | override, public | -| samConversion.kt:2:31:2:45 | new Function1(...) { ... } | samConversion.kt:2:31:2:45 | invoke | override, public | -| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | override, public | -| samConversion.kt:4:27:4:42 | new Function2(...) { ... } | samConversion.kt:4:27:4:42 | invoke | override, public | -| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | override, public | +| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | final, override, public | +| samConversion.kt:2:31:2:45 | new Function1(...) { ... } | samConversion.kt:2:31:2:45 | invoke | final, override, public | +| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | final, override, public | +| samConversion.kt:4:27:4:42 | new Function2(...) { ... } | samConversion.kt:4:27:4:42 | invoke | final, override, public | +| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | final, override, public | | samConversion.kt:5:27:5:31 | new Function2(...) { ... } | samConversion.kt:5:27:5:31 | invoke | override, public | -| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | override, public | -| samConversion.kt:7:29:7:46 | new Function2(...) { ... } | samConversion.kt:7:29:7:46 | invoke | override, public | -| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | override, public | -| samConversion.kt:9:33:11:5 | new Function1(...) { ... } | samConversion.kt:9:33:11:5 | invoke | override, public | -| samConversion.kt:11:12:13:5 | new Function1(...) { ... } | samConversion.kt:11:12:13:5 | invoke | override, public | +| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | final, override, public | +| samConversion.kt:7:29:7:46 | new Function2(...) { ... } | samConversion.kt:7:29:7:46 | invoke | final, override, public | +| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | final, override, public | +| samConversion.kt:9:33:11:5 | new Function1(...) { ... } | samConversion.kt:9:33:11:5 | invoke | final, override, public | +| samConversion.kt:11:12:13:5 | new Function1(...) { ... } | samConversion.kt:11:12:13:5 | invoke | final, override, public | | samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | samConversion.kt:41:13:41:16 | invoke | override, public | -| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | override, public | -| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | override, public | +| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | final, override, public | +| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | final, override, public | +| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | final, public | | samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | override, public | -| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | public | -| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | override, public | -| samConversion.kt:46:32:46:44 | new Function1(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public | -| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend | -| samConversion.kt:58:30:58:45 | new Function2(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | -| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | override, public | +| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | final, override, public | +| samConversion.kt:46:32:46:44 | new Function1(...) { ... } | samConversion.kt:46:32:46:44 | invoke | final, override, public | +| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | final, override, public, suspend | +| samConversion.kt:58:30:58:45 | new Function2(...) { ... } | samConversion.kt:58:30:58:45 | invoke | final, override, public, suspend | +| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | final, override, public | | samConversion.kt:75:27:75:32 | new KProperty0(...) { ... } | samConversion.kt:75:27:75:32 | get | override, public | | samConversion.kt:75:27:75:32 | new KProperty0(...) { ... } | samConversion.kt:75:27:75:32 | invoke | override, public | -| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | override, public | +| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | final, override, public | | samConversion.kt:76:36:76:54 | new KProperty1(...) { ... } | samConversion.kt:76:36:76:54 | get | override, public | | samConversion.kt:76:36:76:54 | new KProperty1(...) { ... } | samConversion.kt:76:36:76:54 | invoke | override, public | nonOverrideInvoke diff --git a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected index 77b2fbb794e..5af83a46a01 100644 --- a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected @@ -27,7 +27,7 @@ A.kt: # 10| 2: [ExprStmt] ; # 10| 0: [MethodAccess] println(...) # 10| -1: [TypeAccess] ConsoleKt -# 10| 0: [StringLiteral] +# 10| 0: [StringLiteral] "" # 13| 6: [Method] getProp # 13| 3: [TypeAccess] int # 13| 5: [BlockStmt] { ... } diff --git a/java/ql/test/kotlin/library-tests/extensions/extensions.kt b/java/ql/test/kotlin/library-tests/extensions/extensions.kt index 8742f55e7b9..b5bc5b8c2cb 100644 --- a/java/ql/test/kotlin/library-tests/extensions/extensions.kt +++ b/java/ql/test/kotlin/library-tests/extensions/extensions.kt @@ -30,8 +30,3 @@ fun foo() { fun String.baz(p1: String): String { return "Baz" } "someString".baz("bazParam") } - -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull diff --git a/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected b/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected index 03322ec3313..4aa35cde90b 100644 --- a/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected +++ b/java/ql/test/kotlin/library-tests/extensions/methodaccesses.expected @@ -1,20 +1,20 @@ | A.java:3:9:3:49 | someFun(...) | A.java:3:9:3:20 | ExtensionsKt | A.java:3:30:3:44 | new SomeClass(...) | | A.java:3:9:3:49 | someFun(...) | A.java:3:9:3:20 | ExtensionsKt | A.java:3:47:3:48 | "" | -| extensions.kt:21:5:21:38 | someClassMethod(...) | extensions.kt:21:5:21:15 | new SomeClass(...) | extensions.kt:21:34:21:36 | foo | +| extensions.kt:21:5:21:38 | someClassMethod(...) | extensions.kt:21:5:21:15 | new SomeClass(...) | extensions.kt:21:34:21:36 | "foo" | | extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:5:22:15 | new SomeClass(...) | -| extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:26:22:28 | foo | +| extensions.kt:22:5:22:30 | someFun(...) | extensions.kt:22:5:22:30 | ExtensionsKt | extensions.kt:22:26:22:28 | "foo" | | extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:5:23:15 | new SomeClass(...) | -| extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:26:23:28 | foo | +| extensions.kt:23:5:23:30 | bothFun(...) | extensions.kt:23:5:23:30 | ExtensionsKt | extensions.kt:23:26:23:28 | "foo" | | extensions.kt:24:5:24:35 | bothFunDiffTypes(...) | extensions.kt:24:5:24:35 | ExtensionsKt | extensions.kt:24:5:24:15 | new SomeClass(...) | | extensions.kt:24:5:24:35 | bothFunDiffTypes(...) | extensions.kt:24:5:24:35 | ExtensionsKt | extensions.kt:24:34:24:34 | 1 | -| extensions.kt:25:5:25:44 | anotherClassMethod(...) | extensions.kt:25:5:25:18 | new AnotherClass(...) | extensions.kt:25:40:25:42 | foo | +| extensions.kt:25:5:25:44 | anotherClassMethod(...) | extensions.kt:25:5:25:18 | new AnotherClass(...) | extensions.kt:25:40:25:42 | "foo" | | extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:5:26:18 | new AnotherClass(...) | -| extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:32:26:34 | foo | +| extensions.kt:26:5:26:36 | anotherFun(...) | extensions.kt:26:5:26:36 | ExtensionsKt | extensions.kt:26:32:26:34 | "foo" | | extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:5:27:18 | new AnotherClass(...) | -| extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:29:27:31 | foo | +| extensions.kt:27:5:27:33 | bothFun(...) | extensions.kt:27:5:27:33 | ExtensionsKt | extensions.kt:27:29:27:31 | "foo" | | extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:5:28:18 | new AnotherClass(...) | -| extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:38:28:40 | foo | -| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:6:29:15 | someString | -| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:23:29:25 | foo | -| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:6:31:15 | someString | -| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:23:31:30 | bazParam | +| extensions.kt:28:5:28:42 | bothFunDiffTypes(...) | extensions.kt:28:5:28:42 | ExtensionsKt | extensions.kt:28:38:28:40 | "foo" | +| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:6:29:15 | "someString" | +| extensions.kt:29:6:29:27 | bar(...) | extensions.kt:29:6:29:27 | ExtensionsKt | extensions.kt:29:23:29:25 | "foo" | +| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:6:31:15 | "someString" | +| extensions.kt:31:6:31:32 | baz(...) | extensions.kt:31:6:31:32 | new (...) | extensions.kt:31:23:31:30 | "bazParam" | diff --git a/java/ql/test/kotlin/library-tests/extensions/parameters.expected b/java/ql/test/kotlin/library-tests/extensions/parameters.expected index 5cb7e0986d3..65906e57dd2 100644 --- a/java/ql/test/kotlin/library-tests/extensions/parameters.expected +++ b/java/ql/test/kotlin/library-tests/extensions/parameters.expected @@ -1,24 +1,24 @@ parametersWithArgs -| extensions.kt:3:25:3:34 | p1 | 0 | extensions.kt:21:34:21:36 | foo | -| extensions.kt:6:28:6:37 | p1 | 0 | extensions.kt:25:40:25:42 | foo | +| extensions.kt:3:25:3:34 | p1 | 0 | extensions.kt:21:34:21:36 | "foo" | +| extensions.kt:6:28:6:37 | p1 | 0 | extensions.kt:25:40:25:42 | "foo" | | extensions.kt:9:5:9:13 | | 0 | A.java:3:30:3:44 | new SomeClass(...) | | extensions.kt:9:5:9:13 | | 0 | extensions.kt:22:5:22:15 | new SomeClass(...) | | extensions.kt:9:23:9:32 | p1 | 1 | A.java:3:47:3:48 | "" | -| extensions.kt:9:23:9:32 | p1 | 1 | extensions.kt:22:26:22:28 | foo | +| extensions.kt:9:23:9:32 | p1 | 1 | extensions.kt:22:26:22:28 | "foo" | | extensions.kt:10:5:10:16 | | 0 | extensions.kt:26:5:26:18 | new AnotherClass(...) | -| extensions.kt:10:29:10:38 | p1 | 1 | extensions.kt:26:32:26:34 | foo | +| extensions.kt:10:29:10:38 | p1 | 1 | extensions.kt:26:32:26:34 | "foo" | | extensions.kt:12:5:12:13 | | 0 | extensions.kt:23:5:23:15 | new SomeClass(...) | -| extensions.kt:12:23:12:32 | p1 | 1 | extensions.kt:23:26:23:28 | foo | +| extensions.kt:12:23:12:32 | p1 | 1 | extensions.kt:23:26:23:28 | "foo" | | extensions.kt:13:5:13:16 | | 0 | extensions.kt:27:5:27:18 | new AnotherClass(...) | -| extensions.kt:13:26:13:35 | p1 | 1 | extensions.kt:27:29:27:31 | foo | +| extensions.kt:13:26:13:35 | p1 | 1 | extensions.kt:27:29:27:31 | "foo" | | extensions.kt:15:5:15:13 | | 0 | extensions.kt:24:5:24:15 | new SomeClass(...) | | extensions.kt:15:32:15:38 | p1 | 1 | extensions.kt:24:34:24:34 | 1 | | extensions.kt:16:5:16:16 | | 0 | extensions.kt:28:5:28:18 | new AnotherClass(...) | -| extensions.kt:16:35:16:44 | p1 | 1 | extensions.kt:28:38:28:40 | foo | -| extensions.kt:18:5:18:10 | | 0 | extensions.kt:29:6:29:15 | someString | -| extensions.kt:18:16:18:25 | p1 | 1 | extensions.kt:29:23:29:25 | foo | -| extensions.kt:30:9:30:14 | | 0 | extensions.kt:31:6:31:15 | someString | -| extensions.kt:30:20:30:29 | p1 | 1 | extensions.kt:31:23:31:30 | bazParam | +| extensions.kt:16:35:16:44 | p1 | 1 | extensions.kt:28:38:28:40 | "foo" | +| extensions.kt:18:5:18:10 | | 0 | extensions.kt:29:6:29:15 | "someString" | +| extensions.kt:18:16:18:25 | p1 | 1 | extensions.kt:29:23:29:25 | "foo" | +| extensions.kt:30:9:30:14 | | 0 | extensions.kt:31:6:31:15 | "someString" | +| extensions.kt:30:20:30:29 | p1 | 1 | extensions.kt:31:23:31:30 | "bazParam" | extensionParameter | extensions.kt:9:5:9:13 | | | extensions.kt:10:5:10:16 | | diff --git a/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected b/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected index deed53a7269..8b6a502898e 100644 --- a/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected +++ b/java/ql/test/kotlin/library-tests/generic-inner-classes/test.expected @@ -2,11 +2,11 @@ callArgs | KotlinUser.kt:7:13:7:31 | new OuterGeneric(...) | KotlinUser.kt:7:13:7:31 | OuterGeneric | -3 | | KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:13:7:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:33:7:61 | InnerGeneric | -3 | -| KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:55:7:59 | hello | 0 | +| KotlinUser.kt:7:33:7:61 | new InnerGeneric(...) | KotlinUser.kt:7:55:7:59 | "hello" | 0 | | KotlinUser.kt:8:14:8:32 | new OuterGeneric(...) | KotlinUser.kt:8:14:8:32 | OuterGeneric | -3 | | KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:14:8:32 | new OuterGeneric(...) | -2 | | KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:34:8:54 | InnerGeneric | -3 | -| KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:48:8:52 | hello | 0 | +| KotlinUser.kt:8:34:8:54 | new InnerGeneric(...) | KotlinUser.kt:8:48:8:52 | "hello" | 0 | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | OuterGeneric | -3 | | KotlinUser.kt:9:33:9:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:9:33:9:49 | new InnerNotGeneric<>(...) | KotlinUser.kt:9:33:9:49 | InnerNotGeneric<> | -3 | @@ -15,11 +15,11 @@ callArgs | KotlinUser.kt:10:31:10:52 | new InnerGeneric(...) | KotlinUser.kt:10:31:10:52 | InnerGeneric | -3 | | KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:19:12:19 | a | -1 | | KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:34:12:34 | 0 | 0 | -| KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:38:12:42 | hello | 1 | +| KotlinUser.kt:12:19:12:44 | returnsecond(...) | KotlinUser.kt:12:38:12:42 | "hello" | 1 | | KotlinUser.kt:13:19:13:31 | identity(...) | KotlinUser.kt:13:19:13:19 | b | -1 | | KotlinUser.kt:13:19:13:31 | identity(...) | KotlinUser.kt:13:30:13:30 | 5 | 0 | | KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:19:14:19 | c | -1 | -| KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:31:14:35 | world | 0 | +| KotlinUser.kt:14:19:14:37 | identity(...) | KotlinUser.kt:14:31:14:35 | "world" | 0 | genericTypes | OuterGeneric.kt:3:1:21:1 | OuterGeneric | OuterGeneric.kt:3:27:3:27 | T | | OuterGeneric.kt:11:3:19:3 | InnerGeneric | OuterGeneric.kt:11:35:11:35 | S | diff --git a/java/ql/test/kotlin/library-tests/generics-location/generics.kt b/java/ql/test/kotlin/library-tests/generics-location/generics.kt index dff06636bb1..c269ceffea3 100644 --- a/java/ql/test/kotlin/library-tests/generics-location/generics.kt +++ b/java/ql/test/kotlin/library-tests/generics-location/generics.kt @@ -9,6 +9,3 @@ class B { val b1 = B() } } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/generics-location/locations.expected b/java/ql/test/kotlin/library-tests/generics-location/locations.expected index bafdc26e216..2cd1f0ead27 100644 --- a/java/ql/test/kotlin/library-tests/generics-location/locations.expected +++ b/java/ql/test/kotlin/library-tests/generics-location/locations.expected @@ -5,7 +5,6 @@ classLocations | main.A | file:///!unknown-binary-location/main/A.class:0:0:0:0 | file:///!unknown-binary-location/main/A.class:0:0:0:0 | | main.A | A.class:0:0:0:0 | A.class:0:0:0:0 | | main.A | file:///!unknown-binary-location/main/A.class:0:0:0:0 | file:///!unknown-binary-location/main/A.class:0:0:0:0 | -| main.B | generics-location.testproj/test.class.files/main/B.class:0:0:0:0 | generics-location.testproj/test.class.files/main/B.class:0:0:0:0 | | main.B | generics.kt:3:1:11:1 | generics.kt:3:1:11:1 | | main.B | generics-location.testproj/test.class.files/main/B.class:0:0:0:0 | generics-location.testproj/test.class.files/main/B.class:0:0:0:0 | | main.B | file:///!unknown-binary-location/main/B.class:0:0:0:0 | file:///!unknown-binary-location/main/B.class:0:0:0:0 | diff --git a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected index 619ba5f3bcc..2c3b395f4f1 100644 --- a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected @@ -45,18 +45,18 @@ generics.kt: # 27| 0: [MethodAccess] f2(...) # 27| -2: [TypeAccess] String # 27| -1: [VarAccess] c1 -# 27| 0: [StringLiteral] +# 27| 0: [StringLiteral] "" # 28| 3: [LocalVariableDeclStmt] var ...; # 28| 1: [LocalVariableDeclExpr] c2 # 28| 0: [ClassInstanceExpr] new C1(...) # 28| -3: [TypeAccess] C1 # 28| 0: [TypeAccess] String # 28| 1: [TypeAccess] Integer -# 28| 0: [StringLiteral] +# 28| 0: [StringLiteral] "" # 29| 4: [ExprStmt] ; # 29| 0: [MethodAccess] f1(...) # 29| -1: [VarAccess] c2 -# 29| 0: [StringLiteral] a +# 29| 0: [StringLiteral] "a" # 30| 5: [LocalVariableDeclStmt] var ...; # 30| 1: [LocalVariableDeclExpr] x2 # 30| 0: [MethodAccess] f2(...) @@ -256,4 +256,4 @@ generics.kt: # 61| -3: [TypeAccess] Local # 61| 0: [TypeAccess] Integer # 61| 0: [VarAccess] t -# 61| 1: [StringLiteral] +# 61| 1: [StringLiteral] "" diff --git a/java/ql/test/kotlin/library-tests/instances/classes.expected b/java/ql/test/kotlin/library-tests/instances/classes.expected index 771d4f32431..72fa8ccccf5 100644 --- a/java/ql/test/kotlin/library-tests/instances/classes.expected +++ b/java/ql/test/kotlin/library-tests/instances/classes.expected @@ -1,4 +1,5 @@ | TestClassA.kt:2:1:3:1 | TestClassA | +| TestClassA.kt:2:1:3:1 | TestClassA<> | | TestClassAUser.kt:0:0:0:0 | TestClassAUserKt | | TestClassAUser.kt:15:1:15:24 | TestClassAUser | | file:///!unknown-binary-location/TestClassA.class:0:0:0:0 | TestClassA | diff --git a/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt b/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt index b9c4397e920..65c8b43c44c 100644 --- a/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt +++ b/java/ql/test/kotlin/library-tests/internal-constructor-called-from-java/test.kt @@ -3,6 +3,3 @@ public class Test() { internal constructor(x: Int, y: Int) : this() { } } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt index f363f769e50..e79e6d2f907 100644 --- a/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt @@ -10,6 +10,3 @@ public class Test { internal fun internalFun() = 3 } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata diff --git a/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected b/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected index 2e674af64ee..52ed7b2ccfe 100644 --- a/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected +++ b/java/ql/test/kotlin/library-tests/java-lang-number-conversions/test.expected @@ -28,6 +28,7 @@ | kotlin.Byte | describeConstable | | kotlin.Byte | div | | kotlin.Byte | doubleValue | +| kotlin.Byte | equals | | kotlin.Byte | floatValue | | kotlin.Byte | inc | | kotlin.Byte | intValue | @@ -39,6 +40,7 @@ | kotlin.Byte | shortValue | | kotlin.Byte | times | | kotlin.Byte | toChar | +| kotlin.Byte | toString | | kotlin.Byte | unaryMinus | | kotlin.Byte | unaryPlus | | kotlin.Number | byteValue | diff --git a/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected b/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected index 978c4777b09..e356679e208 100644 --- a/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/java-map-methods/PrintAst.expected @@ -45,7 +45,7 @@ test.kt: # 9| 0: [ReturnStmt] return ... # 9| 0: [AddExpr] ... + ... # 9| 0: [VarAccess] s -# 9| 1: [StringLiteral] +# 9| 1: [StringLiteral] "" # 10| 5: [Method] fn2 # 10| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -55,7 +55,7 @@ test.kt: # 10| 0: [ReturnStmt] return ... # 10| 0: [AddExpr] ... + ... # 10| 0: [VarAccess] s -# 10| 1: [StringLiteral] +# 10| 1: [StringLiteral] "" # 12| 6: [Method] fn1 # 12| 3: [TypeAccess] int #-----| 4: (Parameters) diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin/Java.java b/java/ql/test/kotlin/library-tests/java_and_kotlin/Java.java index 6240bced9f2..8e9d4895605 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin/Java.java +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin/Java.java @@ -11,9 +11,13 @@ public class Java { return super.fn0(x); } +/* +// Java interop disabled as it currently doesn't work (no symbol fn1(int, Completion<...>) gets created) +// TODO: re-enable this test once a correct function signature is extracted @Override public Object fn1(int x, Continuation $completion) { return super.fn1(x, $completion); } +*/ } } diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt b/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt index 1686e09e02d..63e5ca99455 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin/Kotlin.kt @@ -13,10 +13,3 @@ class Dkotlin : Base() { override fun fn0(x: Int): String = super.fn0(x) override suspend fun fn1(x: Int): String = super.fn1(x) } - -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.Nullable -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.Nullable diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin/test.expected b/java/ql/test/kotlin/library-tests/java_and_kotlin/test.expected index 8da3febb040..fa37843355f 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin/test.expected +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin/test.expected @@ -1,7 +1,6 @@ methods | Java.java:4:7:4:13 | javaFun | javaFun() | | Java.java:10:17:10:19 | fn0 | fn0(int) | -| Java.java:15:17:15:19 | fn1 | fn1(int,kotlin.coroutines.Continuation) | | Kotlin.kt:2:2:4:2 | kotlinFun | kotlinFun() | | Kotlin.kt:8:10:8:38 | fn0 | fn0(int) | | Kotlin.kt:9:18:9:46 | fn1 | fn1(int) | @@ -9,15 +8,12 @@ methods | Kotlin.kt:14:22:14:59 | fn1 | fn1(int) | overrides | Java.java:10:17:10:19 | fn0 | Kotlin.kt:8:10:8:38 | fn0 | -| Java.java:15:17:15:19 | fn1 | java_and_kotlin.testproj/test.class.files/Base.class:0:0:0:0 | fn1 | | Kotlin.kt:13:14:13:51 | fn0 | Kotlin.kt:8:10:8:38 | fn0 | | Kotlin.kt:14:22:14:59 | fn1 | Kotlin.kt:9:18:9:46 | fn1 | signature_mismatch | Kotlin.kt:9:18:9:46 | fn1 | fn1(int) | -| java_and_kotlin.testproj/test.class.files/Base.class:0:0:0:0 | fn1 | fn1(int,kotlin.coroutines.Continuation) | #select | Java.java:5:3:5:26 | kotlinFun(...) | Kotlin.kt:2:2:4:2 | kotlinFun | | Java.java:11:11:11:22 | fn0(...) | Kotlin.kt:8:10:8:38 | fn0 | -| Java.java:16:11:16:35 | fn1(...) | java_and_kotlin.testproj/test.class.files/Base.class:0:0:0:0 | fn1 | | Kotlin.kt:13:40:13:51 | fn0(...) | Kotlin.kt:8:10:8:38 | fn0 | | Kotlin.kt:14:48:14:59 | fn1(...) | Kotlin.kt:9:18:9:46 | fn1 | diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Java.java b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Java.java index 73be4ea80bb..585161f21c0 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Java.java +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Java.java @@ -1,5 +1,6 @@ public class Java { void javaFun() { new Kotlin().kotlinFun$main(); + KotlinKt.topLevelKotlinFun(); } } diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt index 4cdedefbbc8..98235ec7ff8 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/Kotlin.kt @@ -3,5 +3,4 @@ public class Kotlin { } } -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata +internal fun topLevelKotlinFun() { } diff --git a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/visibility.expected b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/visibility.expected index 3edb62a6505..378da6dd22f 100644 --- a/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/visibility.expected +++ b/java/ql/test/kotlin/library-tests/java_and_kotlin_internal/visibility.expected @@ -1,9 +1,16 @@ isPublic isInternal | Kotlin.kt:2:11:3:2 | kotlinFun$main | +| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | modifiers_methods | file://:0:0:0:0 | final | Kotlin.kt:2:11:3:2 | kotlinFun$main | +| file://:0:0:0:0 | final | Kotlin.kt:6:10:6:36 | topLevelKotlinFun | | file://:0:0:0:0 | internal | Kotlin.kt:2:11:3:2 | kotlinFun$main | +| file://:0:0:0:0 | internal | Kotlin.kt:6:10:6:36 | topLevelKotlinFun | +| file://:0:0:0:0 | static | Kotlin.kt:6:10:6:36 | topLevelKotlinFun | #select | Kotlin.kt:2:11:3:2 | kotlinFun$main | final | | Kotlin.kt:2:11:3:2 | kotlinFun$main | internal | +| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | final | +| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | internal | +| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | static | diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected index 6dfd45e83f4..172aac49284 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/PrintAst.expected @@ -5,7 +5,7 @@ test.kt: # 1| 3: [TypeAccess] String # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... -# 1| 0: [StringLiteral] Hello world +# 1| 0: [StringLiteral] "Hello world" # 45| 2: [ExtensionMethod] testExtensionFunction # 45| 3: [TypeAccess] int #-----| 4: (Parameters) @@ -55,6 +55,8 @@ test.kt: # 1| 6: [IntegerLiteral] 23 # 1| 7: [NullLiteral] null # 45| 4: [ExtensionMethod] testExtensionFunction +#-----| 1: (Annotations) +# 44| 1: [Annotation] JvmOverloads # 45| 3: [TypeAccess] int #-----| 4: (Parameters) # 45| 0: [Parameter] @@ -72,7 +74,7 @@ test.kt: # 45| 5: [BlockStmt] { ... } # 45| 0: [ReturnStmt] return ... # 45| 0: [VarAccess] a -# 45| 5: [Method] testExtensionFunction$default +# 45| 5: [ExtensionMethod] testExtensionFunction$default # 45| 3: [TypeAccess] int #-----| 4: (Parameters) # 45| 0: [Parameter] p0 @@ -116,7 +118,7 @@ test.kt: # 45| 2: [ReturnStmt] return ... # 45| 0: [MethodAccess] testExtensionFunction(...) # 45| -1: [TypeAccess] TestKt -# 45| 0: [VarAccess] p0 +# 45| 0: [ExtensionReceiverAccess] this # 45| 1: [VarAccess] p1 # 45| 2: [VarAccess] p2 # 45| 3: [VarAccess] p3 @@ -170,6 +172,9 @@ test.kt: # 1| 5: [IntegerLiteral] 23 # 1| 6: [NullLiteral] null # 6| 4: [Method] testStaticFunction +#-----| 1: (Annotations) +# 5| 1: [Annotation] JvmOverloads +# 5| 2: [Annotation] JvmStatic # 6| 3: [TypeAccess] int #-----| 4: (Parameters) # 6| 0: [Parameter] a @@ -277,6 +282,8 @@ test.kt: # 1| 6: [IntegerLiteral] 23 # 1| 7: [NullLiteral] null # 9| 8: [Method] testMemberFunction +#-----| 1: (Annotations) +# 8| 1: [Annotation] JvmOverloads # 9| 3: [TypeAccess] int #-----| 4: (Parameters) # 9| 0: [Parameter] a @@ -356,9 +363,9 @@ test.kt: # 12| 0: [ReturnStmt] return ... # 12| 0: [MethodAccess] testMemberExtensionFunction$default(...) # 12| -1: [TypeAccess] Test -# 0| 0: [ExtensionReceiverAccess] this -# 0| 1: [ThisAccess] Test.this +# 0| 0: [ThisAccess] Test.this # 0| 0: [TypeAccess] Test +# 0| 1: [ExtensionReceiverAccess] this # 0| 2: [VarAccess] a # 1| 3: [NullLiteral] null # 0| 4: [VarAccess] c @@ -383,9 +390,9 @@ test.kt: # 12| 0: [ReturnStmt] return ... # 12| 0: [MethodAccess] testMemberExtensionFunction$default(...) # 12| -1: [TypeAccess] Test -# 0| 0: [ExtensionReceiverAccess] this -# 0| 1: [ThisAccess] Test.this +# 0| 0: [ThisAccess] Test.this # 0| 0: [TypeAccess] Test +# 0| 1: [ExtensionReceiverAccess] this # 0| 2: [VarAccess] a # 0| 3: [VarAccess] b # 0| 4: [VarAccess] c @@ -394,6 +401,8 @@ test.kt: # 1| 7: [IntegerLiteral] 23 # 1| 8: [NullLiteral] null # 12| 12: [ExtensionMethod] testMemberExtensionFunction +#-----| 1: (Annotations) +# 11| 1: [Annotation] JvmOverloads # 12| 3: [TypeAccess] int #-----| 4: (Parameters) # 12| 0: [Parameter] @@ -411,13 +420,13 @@ test.kt: # 12| 5: [BlockStmt] { ... } # 12| 0: [ReturnStmt] return ... # 12| 0: [VarAccess] a -# 12| 13: [Method] testMemberExtensionFunction$default +# 12| 13: [ExtensionMethod] testMemberExtensionFunction$default # 12| 3: [TypeAccess] int #-----| 4: (Parameters) # 12| 0: [Parameter] p0 -# 12| 0: [TypeAccess] Test2 -# 12| 1: [Parameter] p1 # 12| 0: [TypeAccess] Test +# 12| 1: [Parameter] p1 +# 12| 0: [TypeAccess] Test2 # 12| 2: [Parameter] p2 # 12| 0: [TypeAccess] int # 12| 3: [Parameter] p3 @@ -456,8 +465,8 @@ test.kt: # 12| 1: [FloatLiteral] 1.0 # 12| 2: [ReturnStmt] return ... # 12| 0: [MethodAccess] testMemberExtensionFunction(...) -# 12| -1: [VarAccess] p1 -# 12| 0: [VarAccess] p0 +# 12| -1: [VarAccess] p0 +# 12| 0: [ExtensionReceiverAccess] this # 12| 1: [VarAccess] p2 # 12| 2: [VarAccess] p3 # 12| 3: [VarAccess] p4 @@ -501,6 +510,8 @@ test.kt: # 1| 5: [IntegerLiteral] 23 # 1| 6: [NullLiteral] null # 16| 3: [Constructor] Test2 +#-----| 1: (Annotations) +# 16| 1: [Annotation] JvmOverloads #-----| 4: (Parameters) # 16| 0: [Parameter] a # 16| 0: [TypeAccess] int @@ -609,6 +620,8 @@ test.kt: # 1| 6: [IntegerLiteral] 23 # 1| 7: [NullLiteral] null # 21| 4: [Method] testCompanionFunction +#-----| 1: (Annotations) +# 20| 1: [Annotation] JvmOverloads # 21| 3: [TypeAccess] int #-----| 4: (Parameters) # 21| 0: [Parameter] a @@ -718,6 +731,9 @@ test.kt: # 1| 6: [IntegerLiteral] 23 # 1| 7: [NullLiteral] null # 24| 8: [Method] testStaticCompanionFunction +#-----| 1: (Annotations) +# 23| 1: [Annotation] JvmOverloads +# 23| 2: [Annotation] JvmStatic # 24| 3: [TypeAccess] int #-----| 4: (Parameters) # 24| 0: [Parameter] a @@ -883,6 +899,8 @@ test.kt: # 1| 4: [IntegerLiteral] 11 # 1| 5: [NullLiteral] null # 30| 3: [Constructor] GenericTest +#-----| 1: (Annotations) +# 30| 1: [Annotation] JvmOverloads #-----| 4: (Parameters) # 30| 0: [Parameter] a # 30| 0: [TypeAccess] int @@ -929,7 +947,7 @@ test.kt: # 30| 1: [ExprStmt] ; # 30| 0: [AssignExpr] ...=... # 30| 0: [VarAccess] p2 -# 30| 1: [StringLiteral] Hello world +# 30| 1: [StringLiteral] "Hello world" # 30| 2: [ThisConstructorInvocationStmt] this(...) # 30| 0: [VarAccess] p0 # 30| 1: [VarAccess] p1 @@ -974,6 +992,8 @@ test.kt: # 1| 5: [IntegerLiteral] 11 # 1| 6: [NullLiteral] null # 33| 7: [Method] testMemberFunction +#-----| 1: (Annotations) +# 32| 1: [Annotation] JvmOverloads # 33| 3: [TypeAccess] int #-----| 4: (Parameters) # 33| 0: [Parameter] a @@ -1024,7 +1044,7 @@ test.kt: # 33| 1: [ExprStmt] ; # 33| 0: [AssignExpr] ...=... # 33| 0: [VarAccess] p3 -# 33| 1: [StringLiteral] Hello world +# 33| 1: [StringLiteral] "Hello world" # 33| 2: [ReturnStmt] return ... # 33| 0: [MethodAccess] testMemberFunction(...) # 33| -1: [VarAccess] p0 @@ -1049,7 +1069,7 @@ test.kt: # 37| -1: [VarAccess] spec1 # 37| 0: [IntegerLiteral] 1 # 37| 1: [FloatLiteral] 1.0 -# 37| 2: [StringLiteral] Hello world +# 37| 2: [StringLiteral] "Hello world" # 37| 3: [FloatLiteral] 2.0 # 38| 1: [ExprStmt] ; # 38| 0: [ImplicitCoercionToUnitExpr] @@ -1058,5 +1078,5 @@ test.kt: # 38| -1: [VarAccess] spec2 # 38| 0: [IntegerLiteral] 1 # 38| 1: [DoubleLiteral] 1.0 -# 38| 2: [StringLiteral] Hello world +# 38| 2: [StringLiteral] "Hello world" # 38| 3: [DoubleLiteral] 2.0 diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/test.expected b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/test.expected index 00654e8929f..5fcccaca991 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/test.expected +++ b/java/ql/test/kotlin/library-tests/jvmoverloads-annotation/test.expected @@ -29,7 +29,7 @@ | test.kt:3:1:14:1 | Test | test.kt:12:3:12:121 | testMemberExtensionFunction | testMemberExtensionFunction(Test2,int,double,boolean) | | test.kt:3:1:14:1 | Test | test.kt:12:3:12:121 | testMemberExtensionFunction | testMemberExtensionFunction(Test2,int,java.lang.String,double,boolean) | | test.kt:3:1:14:1 | Test | test.kt:12:3:12:121 | testMemberExtensionFunction | testMemberExtensionFunction(Test2,int,java.lang.String,double,float,boolean) | -| test.kt:3:1:14:1 | Test | test.kt:12:3:12:121 | testMemberExtensionFunction$default | testMemberExtensionFunction$default(Test2,Test,int,java.lang.String,double,float,boolean,int,java.lang.Object) | +| test.kt:3:1:14:1 | Test | test.kt:12:3:12:121 | testMemberExtensionFunction$default | testMemberExtensionFunction$default(Test,Test2,int,java.lang.String,double,float,boolean,int,java.lang.Object) | | test.kt:16:1:28:1 | Test2 | test.kt:16:34:28:1 | Test2 | Test2(int,double,boolean) | | test.kt:16:1:28:1 | Test2 | test.kt:16:34:28:1 | Test2 | Test2(int,java.lang.String,double,boolean) | | test.kt:16:1:28:1 | Test2 | test.kt:16:34:28:1 | Test2 | Test2(int,java.lang.String,double,float,boolean) | diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt b/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt index f7e42c682df..ff5879ebb93 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmoverloads_flow/test.kt @@ -85,14 +85,3 @@ public class TestDefaultParameterReference { } } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull -// Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmOverloads -// Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmStatic -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.Nullable -// Diagnostic Matches: Unknown location for kotlin.jvm.JvmOverloads -// Diagnostic Matches: Unknown location for kotlin.jvm.JvmStatic -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.Nullable diff --git a/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt b/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt index ee49968eb57..3e5ced39c3f 100644 --- a/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmoverloads_generics/test.kt @@ -4,10 +4,3 @@ public class A { fun genericFunctionWithOverloads(x: T? = null, y: List? = null, z: T? = null): T? = z } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmOverloads -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.Nullable -// Diagnostic Matches: Unknown location for kotlin.jvm.JvmOverloads -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.Nullable diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected index 1376baa4f1d..338e67a33b0 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -81,13 +81,13 @@ test.kt: # 52| 0: [TypeAccess] Unit # 52| 1: [MethodAccess] staticMethod(...) # 52| -1: [VarAccess] Companion -# 52| 0: [StringLiteral] 1 +# 52| 0: [StringLiteral] "1" # 53| 1: [ExprStmt] ; # 53| 0: [ImplicitCoercionToUnitExpr] # 53| 0: [TypeAccess] Unit # 53| 1: [MethodAccess] nonStaticMethod(...) # 53| -1: [VarAccess] Companion -# 53| 0: [StringLiteral] 2 +# 53| 0: [StringLiteral] "2" # 54| 2: [ExprStmt] ; # 54| 0: [MethodAccess] setStaticProp(...) # 54| -1: [VarAccess] Companion @@ -113,13 +113,13 @@ test.kt: # 60| 0: [TypeAccess] Unit # 60| 1: [MethodAccess] staticMethod(...) # 60| -1: [TypeAccess] NonCompanion -# 60| 0: [StringLiteral] 1 +# 60| 0: [StringLiteral] "1" # 61| 7: [ExprStmt] ; # 61| 0: [ImplicitCoercionToUnitExpr] # 61| 0: [TypeAccess] Unit # 61| 1: [MethodAccess] nonStaticMethod(...) # 61| -1: [VarAccess] INSTANCE -# 61| 0: [StringLiteral] 2 +# 61| 0: [StringLiteral] "2" # 62| 8: [ExprStmt] ; # 62| 0: [MethodAccess] setStaticProp(...) # 62| -1: [TypeAccess] NonCompanion @@ -141,13 +141,11 @@ test.kt: # 65| 0: [MethodAccess] getPropWithStaticGetter(...) # 65| -1: [TypeAccess] NonCompanion # 9| 2: [Class] HasCompanion -#-----| -3: (Annotations) -# 9| 2: [Constructor] HasCompanion +# 9| 1: [Constructor] HasCompanion # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) # 9| 1: [BlockStmt] { ... } -# 11| 3: [Class] Companion -#-----| -3: (Annotations) +# 11| 2: [Class] Companion # 11| 1: [Constructor] Companion # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) @@ -160,10 +158,10 @@ test.kt: # 17| 0: [VarAccess] nonStaticProp # 13| 2: [Method] staticMethod #-----| 1: (Annotations) +# 13| 1: [Annotation] JvmStatic # 13| 3: [TypeAccess] String #-----| 4: (Parameters) # 13| 0: [Parameter] s -#-----| -1: (Annotations) # 13| 0: [TypeAccess] String # 13| 5: [BlockStmt] { ... } # 13| 0: [ReturnStmt] return ... @@ -171,11 +169,9 @@ test.kt: # 13| -1: [ThisAccess] this # 13| 0: [VarAccess] s # 14| 3: [Method] nonStaticMethod -#-----| 1: (Annotations) # 14| 3: [TypeAccess] String #-----| 4: (Parameters) # 14| 0: [Parameter] s -#-----| -1: (Annotations) # 14| 0: [TypeAccess] String # 14| 5: [BlockStmt] { ... } # 14| 0: [ReturnStmt] return ... @@ -184,9 +180,8 @@ test.kt: # 14| 0: [VarAccess] s # 16| 4: [FieldDeclaration] String staticProp; # 16| -1: [TypeAccess] String -# 16| 0: [StringLiteral] a +# 16| 0: [StringLiteral] "a" # 16| 5: [Method] getStaticProp -#-----| 1: (Annotations) # 16| 3: [TypeAccess] String # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... @@ -196,7 +191,6 @@ test.kt: # 16| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 16| 0: [Parameter] -#-----| -1: (Annotations) # 16| 0: [TypeAccess] String # 16| 5: [BlockStmt] { ... } # 16| 0: [ExprStmt] ; @@ -206,9 +200,8 @@ test.kt: # 16| 1: [VarAccess] # 17| 7: [FieldDeclaration] String nonStaticProp; # 17| -1: [TypeAccess] String -# 17| 0: [StringLiteral] b +# 17| 0: [StringLiteral] "b" # 17| 8: [Method] getNonStaticProp -#-----| 1: (Annotations) # 17| 3: [TypeAccess] String # 17| 5: [BlockStmt] { ... } # 17| 0: [ReturnStmt] return ... @@ -218,7 +211,6 @@ test.kt: # 17| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 17| 0: [Parameter] -#-----| -1: (Annotations) # 17| 0: [TypeAccess] String # 17| 5: [BlockStmt] { ... } # 17| 0: [ExprStmt] ; @@ -228,6 +220,7 @@ test.kt: # 17| 1: [VarAccess] # 20| 10: [Method] getPropWithStaticGetter #-----| 1: (Annotations) +# 20| 1: [Annotation] JvmStatic # 20| 3: [TypeAccess] String # 20| 5: [BlockStmt] { ... } # 20| 0: [ReturnStmt] return ... @@ -237,7 +230,6 @@ test.kt: # 21| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 21| 0: [Parameter] s -#-----| -1: (Annotations) # 21| 0: [TypeAccess] String # 21| 5: [BlockStmt] { ... } # 21| 0: [ExprStmt] ; @@ -245,7 +237,6 @@ test.kt: # 21| -1: [ThisAccess] this # 21| 0: [VarAccess] s # 24| 12: [Method] getPropWithStaticSetter -#-----| 1: (Annotations) # 24| 3: [TypeAccess] String # 24| 5: [BlockStmt] { ... } # 24| 0: [ReturnStmt] return ... @@ -253,22 +244,20 @@ test.kt: # 24| -1: [ThisAccess] this # 25| 13: [Method] setPropWithStaticSetter #-----| 1: (Annotations) +# 25| 1: [Annotation] JvmStatic # 25| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 25| 0: [Parameter] s -#-----| -1: (Annotations) # 25| 0: [TypeAccess] String # 25| 5: [BlockStmt] { ... } # 25| 0: [ExprStmt] ; # 25| 0: [MethodAccess] setPropWithStaticGetter(...) # 25| -1: [ThisAccess] this # 25| 0: [VarAccess] s -# 13| 4: [Method] staticMethod -#-----| 1: (Annotations) +# 13| 3: [Method] staticMethod # 13| 3: [TypeAccess] String #-----| 4: (Parameters) # 13| 0: [Parameter] s -#-----| -1: (Annotations) # 13| 0: [TypeAccess] String # 13| 5: [BlockStmt] { ... } # 13| 0: [ReturnStmt] return ... @@ -276,19 +265,17 @@ test.kt: # 13| -1: [VarAccess] HasCompanion.Companion # 13| -1: [TypeAccess] HasCompanion # 13| 0: [VarAccess] s -# 16| 5: [Method] getStaticProp -#-----| 1: (Annotations) +# 16| 4: [Method] getStaticProp # 16| 3: [TypeAccess] String # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... # 16| 0: [MethodAccess] getStaticProp(...) # 16| -1: [VarAccess] HasCompanion.Companion # 16| -1: [TypeAccess] HasCompanion -# 16| 6: [Method] setStaticProp +# 16| 5: [Method] setStaticProp # 16| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 16| 0: [Parameter] -#-----| -1: (Annotations) # 16| 0: [TypeAccess] String # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... @@ -296,20 +283,17 @@ test.kt: # 16| -1: [VarAccess] HasCompanion.Companion # 16| -1: [TypeAccess] HasCompanion # 16| 0: [VarAccess] -# 20| 7: [Method] getPropWithStaticGetter -#-----| 1: (Annotations) +# 20| 6: [Method] getPropWithStaticGetter # 20| 3: [TypeAccess] String # 20| 5: [BlockStmt] { ... } # 20| 0: [ReturnStmt] return ... # 20| 0: [MethodAccess] getPropWithStaticGetter(...) # 20| -1: [VarAccess] HasCompanion.Companion # 20| -1: [TypeAccess] HasCompanion -# 25| 8: [Method] setPropWithStaticSetter -#-----| 1: (Annotations) +# 25| 7: [Method] setPropWithStaticSetter # 25| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 25| 0: [Parameter] s -#-----| -1: (Annotations) # 25| 0: [TypeAccess] String # 25| 5: [BlockStmt] { ... } # 25| 0: [ReturnStmt] return ... @@ -318,8 +302,7 @@ test.kt: # 25| -1: [TypeAccess] HasCompanion # 25| 0: [VarAccess] s # 31| 3: [Class] NonCompanion -#-----| -3: (Annotations) -# 31| 2: [Constructor] NonCompanion +# 31| 1: [Constructor] NonCompanion # 31| 5: [BlockStmt] { ... } # 31| 0: [SuperConstructorInvocationStmt] super(...) # 31| 1: [BlockStmt] { ... } @@ -329,12 +312,12 @@ test.kt: # 37| 1: [ExprStmt] ; # 37| 0: [KtInitializerAssignExpr] ...=... # 37| 0: [VarAccess] nonStaticProp -# 33| 3: [Method] staticMethod +# 33| 2: [Method] staticMethod #-----| 1: (Annotations) +# 33| 1: [Annotation] JvmStatic # 33| 3: [TypeAccess] String #-----| 4: (Parameters) # 33| 0: [Parameter] s -#-----| -1: (Annotations) # 33| 0: [TypeAccess] String # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... @@ -342,34 +325,30 @@ test.kt: # 33| -1: [VarAccess] NonCompanion.INSTANCE # 33| -1: [TypeAccess] NonCompanion # 33| 0: [VarAccess] s -# 34| 4: [Method] nonStaticMethod -#-----| 1: (Annotations) +# 34| 3: [Method] nonStaticMethod # 34| 3: [TypeAccess] String #-----| 4: (Parameters) # 34| 0: [Parameter] s -#-----| -1: (Annotations) # 34| 0: [TypeAccess] String # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] staticMethod(...) # 34| -1: [TypeAccess] NonCompanion # 34| 0: [VarAccess] s -# 36| 5: [FieldDeclaration] String staticProp; +# 36| 4: [FieldDeclaration] String staticProp; # 36| -1: [TypeAccess] String -# 36| 0: [StringLiteral] a -# 36| 6: [Method] getStaticProp -#-----| 1: (Annotations) +# 36| 0: [StringLiteral] "a" +# 36| 5: [Method] getStaticProp # 36| 3: [TypeAccess] String # 36| 5: [BlockStmt] { ... } # 36| 0: [ReturnStmt] return ... # 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp # 36| -1: [VarAccess] NonCompanion.INSTANCE # 36| -1: [TypeAccess] NonCompanion -# 36| 7: [Method] setStaticProp +# 36| 6: [Method] setStaticProp # 36| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 36| 0: [Parameter] -#-----| -1: (Annotations) # 36| 0: [TypeAccess] String # 36| 5: [BlockStmt] { ... } # 36| 0: [ExprStmt] ; @@ -378,21 +357,19 @@ test.kt: # 36| -1: [VarAccess] NonCompanion.INSTANCE # 36| -1: [TypeAccess] NonCompanion # 36| 1: [VarAccess] -# 37| 8: [FieldDeclaration] String nonStaticProp; +# 37| 7: [FieldDeclaration] String nonStaticProp; # 37| -1: [TypeAccess] String -# 37| 0: [StringLiteral] b -# 37| 9: [Method] getNonStaticProp -#-----| 1: (Annotations) +# 37| 0: [StringLiteral] "b" +# 37| 8: [Method] getNonStaticProp # 37| 3: [TypeAccess] String # 37| 5: [BlockStmt] { ... } # 37| 0: [ReturnStmt] return ... # 37| 0: [VarAccess] this.nonStaticProp # 37| -1: [ThisAccess] this -# 37| 10: [Method] setNonStaticProp +# 37| 9: [Method] setNonStaticProp # 37| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 37| 0: [Parameter] -#-----| -1: (Annotations) # 37| 0: [TypeAccess] String # 37| 5: [BlockStmt] { ... } # 37| 0: [ExprStmt] ; @@ -400,38 +377,37 @@ test.kt: # 37| 0: [VarAccess] this.nonStaticProp # 37| -1: [ThisAccess] this # 37| 1: [VarAccess] -# 40| 11: [Method] getPropWithStaticGetter +# 40| 10: [Method] getPropWithStaticGetter #-----| 1: (Annotations) +# 40| 1: [Annotation] JvmStatic # 40| 3: [TypeAccess] String # 40| 5: [BlockStmt] { ... } # 40| 0: [ReturnStmt] return ... # 40| 0: [MethodAccess] getPropWithStaticSetter(...) # 40| -1: [VarAccess] NonCompanion.INSTANCE # 40| -1: [TypeAccess] NonCompanion -# 41| 12: [Method] setPropWithStaticGetter +# 41| 11: [Method] setPropWithStaticGetter # 41| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 41| 0: [Parameter] s -#-----| -1: (Annotations) # 41| 0: [TypeAccess] String # 41| 5: [BlockStmt] { ... } # 41| 0: [ExprStmt] ; # 41| 0: [MethodAccess] setPropWithStaticSetter(...) # 41| -1: [TypeAccess] NonCompanion # 41| 0: [VarAccess] s -# 44| 13: [Method] getPropWithStaticSetter -#-----| 1: (Annotations) +# 44| 12: [Method] getPropWithStaticSetter # 44| 3: [TypeAccess] String # 44| 5: [BlockStmt] { ... } # 44| 0: [ReturnStmt] return ... # 44| 0: [MethodAccess] getPropWithStaticGetter(...) # 44| -1: [TypeAccess] NonCompanion -# 45| 14: [Method] setPropWithStaticSetter +# 45| 13: [Method] setPropWithStaticSetter #-----| 1: (Annotations) +# 45| 1: [Annotation] JvmStatic # 45| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 45| 0: [Parameter] s -#-----| -1: (Annotations) # 45| 0: [TypeAccess] String # 45| 5: [BlockStmt] { ... } # 45| 0: [ExprStmt] ; diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt index 6f7014723a2..cbf553725b4 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt @@ -65,10 +65,3 @@ fun externalUser() { NonCompanion.propWithStaticSetter = NonCompanion.propWithStaticGetter } - -// Diagnostic Matches: Incomplete annotation: @kotlin.Metadata(%) -// Diagnostic Matches: Unknown location for kotlin.Metadata -// Diagnostic Matches: Completion failure for type: kotlin.jvm.JvmStatic -// Diagnostic Matches: Completion failure for type: org.jetbrains.annotations.NotNull -// Diagnostic Matches: Unknown location for kotlin.jvm.JvmStatic -// Diagnostic Matches: Unknown location for org.jetbrains.annotations.NotNull diff --git a/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected b/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected index c2119ec6123..9f482ab3b71 100644 --- a/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/lateinit/PrintAst.expected @@ -30,7 +30,7 @@ test.kt: # 4| 0: [ReturnStmt] return ... # 4| 0: [MethodAccess] println(...) # 4| -1: [TypeAccess] ConsoleKt -# 4| 0: [StringLiteral] a +# 4| 0: [StringLiteral] "a" # 6| 6: [Method] init # 6| 3: [TypeAccess] LateInit # 6| 5: [BlockStmt] { ... } diff --git a/java/ql/test/kotlin/library-tests/literals/literals.expected b/java/ql/test/kotlin/library-tests/literals/literals.expected index 86d23aa0d05..a22709ce194 100644 --- a/java/ql/test/kotlin/library-tests/literals/literals.expected +++ b/java/ql/test/kotlin/library-tests/literals/literals.expected @@ -23,7 +23,7 @@ | literals.kt:25:34:25:39 | -123.4 | DoubleLiteral | | literals.kt:26:30:26:32 | c | CharacterLiteral | | literals.kt:27:30:27:33 | \n | CharacterLiteral | -| literals.kt:28:34:28:35 | | StringLiteral | -| literals.kt:29:35:29:45 | Some string | StringLiteral | -| literals.kt:30:35:30:46 | Some\nstring | StringLiteral | +| literals.kt:28:34:28:35 | "" | StringLiteral | +| literals.kt:29:35:29:45 | "Some string" | StringLiteral | +| literals.kt:30:35:30:46 | "Some\\nstring" | StringLiteral | | literals.kt:31:30:31:33 | null | NullLiteral | diff --git a/java/ql/test/kotlin/library-tests/literals/literals.ql b/java/ql/test/kotlin/library-tests/literals/literals.ql index db19beff30b..587a71f3dc7 100644 --- a/java/ql/test/kotlin/library-tests/literals/literals.ql +++ b/java/ql/test/kotlin/library-tests/literals/literals.ql @@ -1,4 +1,5 @@ import java from Literal l +where l.getFile().isSourceFile() select l, l.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index 76a48c189c4..5de17a12bf9 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -17,10 +17,13 @@ | dataClass.kt:0:0:0:0 | 1 | IntegerLiteral | | dataClass.kt:0:0:0:0 | 2 | IntegerLiteral | | dataClass.kt:0:0:0:0 | 31 | IntegerLiteral | +| dataClass.kt:0:0:0:0 | ")" | StringLiteral | +| dataClass.kt:0:0:0:0 | ", " | StringLiteral | | dataClass.kt:0:0:0:0 | "..." | StringTemplateExpr | +| dataClass.kt:0:0:0:0 | "DataClass(" | StringLiteral | +| dataClass.kt:0:0:0:0 | "x=" | StringLiteral | +| dataClass.kt:0:0:0:0 | "y=" | StringLiteral | | dataClass.kt:0:0:0:0 | (...)... | CastExpr | -| dataClass.kt:0:0:0:0 | ) | StringLiteral | -| dataClass.kt:0:0:0:0 | , | StringLiteral | | dataClass.kt:0:0:0:0 | ... !is ... | NotInstanceOfExpr | | dataClass.kt:0:0:0:0 | ... & ... | AndBitwiseExpr | | dataClass.kt:0:0:0:0 | ... & ... | AndBitwiseExpr | @@ -40,7 +43,6 @@ | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | | dataClass.kt:0:0:0:0 | DataClass | TypeAccess | -| dataClass.kt:0:0:0:0 | DataClass( | StringLiteral | | dataClass.kt:0:0:0:0 | Object | TypeAccess | | dataClass.kt:0:0:0:0 | Object | TypeAccess | | dataClass.kt:0:0:0:0 | String | TypeAccess | @@ -105,9 +107,7 @@ | dataClass.kt:0:0:0:0 | when ... | WhenExpr | | dataClass.kt:0:0:0:0 | when ... | WhenExpr | | dataClass.kt:0:0:0:0 | x | VarAccess | -| dataClass.kt:0:0:0:0 | x= | StringLiteral | | dataClass.kt:0:0:0:0 | y | VarAccess | -| dataClass.kt:0:0:0:0 | y= | StringLiteral | | dataClass.kt:1:22:1:31 | ...=... | KtInitializerAssignExpr | | dataClass.kt:1:22:1:31 | int | TypeAccess | | dataClass.kt:1:22:1:31 | int | TypeAccess | @@ -204,7 +204,7 @@ | delegates.kt:8:35:11:5 | | VarAccess | | delegates.kt:8:35:11:5 | String | TypeAccess | | delegates.kt:8:35:11:5 | observable(...) | MethodAccess | -| delegates.kt:8:57:8:62 | | StringLiteral | +| delegates.kt:8:57:8:62 | "" | StringLiteral | | delegates.kt:8:66:11:5 | ...->... | LambdaExpr | | delegates.kt:8:66:11:5 | Function3,String,String,Unit> | TypeAccess | | delegates.kt:8:66:11:5 | KProperty | TypeAccess | @@ -219,9 +219,9 @@ | delegates.kt:10:9:10:37 | ConsoleKt | TypeAccess | | delegates.kt:10:9:10:37 | println(...) | MethodAccess | | delegates.kt:10:17:10:36 | "..." | StringTemplateExpr | -| delegates.kt:10:18:10:21 | Was | StringLiteral | +| delegates.kt:10:18:10:21 | "Was " | StringLiteral | | delegates.kt:10:23:10:25 | old | VarAccess | -| delegates.kt:10:26:10:31 | , now | StringLiteral | +| delegates.kt:10:26:10:31 | ", now " | StringLiteral | | delegates.kt:10:33:10:35 | new | VarAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | @@ -293,16 +293,51 @@ | methods2.kt:8:5:9:5 | Unit | TypeAccess | | methods2.kt:8:27:8:32 | int | TypeAccess | | methods2.kt:8:35:8:40 | int | TypeAccess | -| methods3.kt:3:1:3:42 | Unit | TypeAccess | -| methods3.kt:3:5:3:7 | int | TypeAccess | -| methods3.kt:3:33:3:38 | int | TypeAccess | -| methods3.kt:6:5:6:46 | Unit | TypeAccess | -| methods3.kt:6:9:6:11 | int | TypeAccess | -| methods3.kt:6:37:6:42 | int | TypeAccess | +| methods3.kt:3:1:3:49 | 0 | IntegerLiteral | +| methods3.kt:3:1:3:49 | 1 | IntegerLiteral | +| methods3.kt:3:1:3:49 | ... & ... | AndBitwiseExpr | +| methods3.kt:3:1:3:49 | ... == ... | EQExpr | +| methods3.kt:3:1:3:49 | ...=... | AssignExpr | +| methods3.kt:3:1:3:49 | Methods3Kt | TypeAccess | +| methods3.kt:3:1:3:49 | Object | TypeAccess | +| methods3.kt:3:1:3:49 | String | TypeAccess | +| methods3.kt:3:1:3:49 | Unit | TypeAccess | +| methods3.kt:3:1:3:49 | Unit | TypeAccess | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt(...) | MethodAccess | +| methods3.kt:3:1:3:49 | int | TypeAccess | +| methods3.kt:3:1:3:49 | int | TypeAccess | +| methods3.kt:3:1:3:49 | p1 | VarAccess | +| methods3.kt:3:1:3:49 | p1 | VarAccess | +| methods3.kt:3:1:3:49 | p2 | VarAccess | +| methods3.kt:3:1:3:49 | this | ExtensionReceiverAccess | +| methods3.kt:3:5:3:10 | String | TypeAccess | +| methods3.kt:3:36:3:45 | int | TypeAccess | +| methods3.kt:3:45:3:45 | 1 | IntegerLiteral | +| methods3.kt:6:5:6:45 | 0 | IntegerLiteral | +| methods3.kt:6:5:6:45 | 1 | IntegerLiteral | +| methods3.kt:6:5:6:45 | ... & ... | AndBitwiseExpr | +| methods3.kt:6:5:6:45 | ... == ... | EQExpr | +| methods3.kt:6:5:6:45 | ...=... | AssignExpr | +| methods3.kt:6:5:6:45 | Class3 | TypeAccess | +| methods3.kt:6:5:6:45 | Object | TypeAccess | +| methods3.kt:6:5:6:45 | String | TypeAccess | +| methods3.kt:6:5:6:45 | Unit | TypeAccess | +| methods3.kt:6:5:6:45 | Unit | TypeAccess | +| methods3.kt:6:5:6:45 | fooBarMethodExt(...) | MethodAccess | +| methods3.kt:6:5:6:45 | int | TypeAccess | +| methods3.kt:6:5:6:45 | int | TypeAccess | +| methods3.kt:6:5:6:45 | p0 | VarAccess | +| methods3.kt:6:5:6:45 | p2 | VarAccess | +| methods3.kt:6:5:6:45 | p2 | VarAccess | +| methods3.kt:6:5:6:45 | p3 | VarAccess | +| methods3.kt:6:5:6:45 | this | ExtensionReceiverAccess | +| methods3.kt:6:9:6:14 | String | TypeAccess | +| methods3.kt:6:32:6:41 | int | TypeAccess | +| methods3.kt:6:41:6:41 | 1 | IntegerLiteral | | methods4.kt:7:5:7:34 | Unit | TypeAccess | | methods4.kt:7:11:7:29 | InsideNestedTest | TypeAccess | | methods5.kt:3:1:11:1 | Unit | TypeAccess | -| methods5.kt:4:3:4:11 | x | LocalVariableDeclExpr | +| methods5.kt:4:7:4:7 | x | LocalVariableDeclExpr | | methods5.kt:4:11:4:11 | 5 | IntegerLiteral | | methods5.kt:5:3:5:27 | int | TypeAccess | | methods5.kt:5:13:5:18 | int | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.ql b/java/ql/test/kotlin/library-tests/methods/exprs.ql index 6ded7c0026d..c2ae4f55ac7 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.ql +++ b/java/ql/test/kotlin/library-tests/methods/exprs.ql @@ -1,4 +1,5 @@ import java from Expr e +where e.getFile().isSourceFile() select e, e.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 6a86ea6bf5b..89cdd03f303 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -1,59 +1,61 @@ methods | clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:0:0:0:0 | | () | static | Compiler generated | -| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | getTopLevelInt | getTopLevelInt() | public, static | Compiler generated | -| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | setTopLevelInt | setTopLevelInt(int) | public, static | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component1 | component1() | public | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component2 | component2() | public | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy | copy(int,java.lang.String) | public | Compiler generated | +| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | getTopLevelInt | getTopLevelInt() | final, public, static | Compiler generated | +| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | setTopLevelInt | setTopLevelInt(int) | final, public, static | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component1 | component1() | final, public | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component2 | component2() | final, public | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy | copy(int,java.lang.String) | final, public | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy$default | copy$default(DataClass,int,java.lang.String,int,java.lang.Object) | public, static | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | equals | equals(java.lang.Object) | override, public | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | hashCode | hashCode() | override, public | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | toString | toString() | override, public | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:22:1:31 | getX | getX() | public | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | getY | getY() | public | Compiler generated | -| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | setY | setY(java.lang.String) | public | Compiler generated | -| delegates.kt:3:1:12:1 | MyClass | delegates.kt:4:18:6:5 | getLazyProp | getLazyProp() | public | Compiler generated | -| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | getObservableProp | getObservableProp() | public | Compiler generated | -| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | setObservableProp | setObservableProp(java.lang.String) | public | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:22:1:31 | getX | getX() | final, public | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | getY | getY() | final, public | Compiler generated | +| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | setY | setY(java.lang.String) | final, public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:4:18:6:5 | getLazyProp | getLazyProp() | final, public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | getObservableProp | getObservableProp() | final, public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | setObservableProp | setObservableProp(java.lang.String) | final, public | Compiler generated | | delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | get | get(MyClass) | override, public | | | delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | invoke | invoke(MyClass) | override, public | | -| delegates.kt:4:26:6:5 | new Function0(...) { ... } | delegates.kt:4:26:6:5 | invoke | invoke() | override, public | | +| delegates.kt:4:26:6:5 | new Function0(...) { ... } | delegates.kt:4:26:6:5 | invoke | invoke() | final, override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | | | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | | -| delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | override, public | | +| delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | final, override, public | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | | () | static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | public | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | final, public | Compiler generated | | enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | | () | static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | public | | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | public | | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | abstract, public | | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | abstract, public | | | enumClass.kt:8:3:11:4 | VAL | enumClass.kt:9:14:9:30 | f | f(int) | override, public | | | enumClass.kt:8:3:11:4 | VAL | enumClass.kt:10:14:10:42 | g | g(int) | override, public | | -| methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | public, static | | -| methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | public | | -| methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public, static | | -| methods3.kt:5:1:7:1 | Class3 | methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public | | -| methods4.kt:5:3:9:3 | InsideNestedTest | methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) | public | | -| methods5.kt:0:0:0:0 | Methods5Kt | methods5.kt:3:1:11:1 | x | x() | public, static | | -| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | public | | -| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | public | | -| methods6.kt:0:0:0:0 | Methods6Kt | methods6.kt:3:9:4:1 | s | s() | public, static, suspend | | -| methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | public, static | | -| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | | -| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | | -| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | | -| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | | -| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | | -| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun$main | internalFun$main() | internal | | -| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | -| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | inline, public | | +| methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | final, public, static | | +| methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | final, public | | +| methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(java.lang.String,int) | final, public, static | | +| methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | fooBarTopLevelMethodExt$default(java.lang.String,int,int,java.lang.Object) | public, static | Compiler generated | +| methods3.kt:5:1:7:1 | Class3 | methods3.kt:6:5:6:45 | fooBarMethodExt | fooBarMethodExt(java.lang.String,int) | final, public | | +| methods3.kt:5:1:7:1 | Class3 | methods3.kt:6:5:6:45 | fooBarMethodExt$default | fooBarMethodExt$default(foo.bar.Class3,java.lang.String,int,int,java.lang.Object) | public, static | Compiler generated | +| methods4.kt:5:3:9:3 | InsideNestedTest | methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) | final, public | | +| methods5.kt:0:0:0:0 | Methods5Kt | methods5.kt:3:1:11:1 | x | x() | final, public, static | | +| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | final, public | | +| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | final, public | | +| methods6.kt:0:0:0:0 | Methods6Kt | methods6.kt:3:9:4:1 | s | s() | final, public, static, suspend | | +| methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | final, public, static | | +| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | final, public | | +| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | final, public | | +| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | final, public | | +| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | final, protected | | +| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | final, private | | +| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun$main | internalFun$main() | final, internal | | +| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | final, public | | +| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | final, inline, public | | constructors | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:6:1:47 | DataClass | DataClass(int,java.lang.String) | | delegates.kt:3:1:12:1 | MyClass | delegates.kt:3:1:12:1 | MyClass | MyClass() | @@ -74,6 +76,15 @@ constructors | methods5.kt:13:1:13:14 | C1 | methods5.kt:13:1:13:14 | C1 | C1() | | methods.kt:5:1:20:1 | Class | methods.kt:5:1:20:1 | Class | Class() | extensions -| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int | -| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:6:5:6:45 | fooBarMethodExt | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | | methods5.kt:9:3:9:32 | f1 | file:///!unknown-binary-location/foo/bar/C1.class:0:0:0:0 | C1 | +extensionsMismatch +extensionIndex +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt | 0 | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | 0 | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:6:5:6:45 | fooBarMethodExt | 0 | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | 1 | file:///modules/java.base/java/lang/String.class:0:0:0:0 | String | +| methods5.kt:9:3:9:32 | f1 | 0 | file:///!unknown-binary-location/foo/bar/C1.class:0:0:0:0 | C1 | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.ql b/java/ql/test/kotlin/library-tests/methods/methods.ql index 365d41ff1ee..0f0b43f4e4b 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.ql +++ b/java/ql/test/kotlin/library-tests/methods/methods.ql @@ -17,3 +17,19 @@ query predicate constructors(RefType declType, Constructor c, string signature) } query predicate extensions(ExtensionMethod m, Type t) { m.getExtendedType() = t and m.fromSource() } + +query predicate extensionsMismatch(Method src, Method def) { + src.getKotlinParameterDefaultsProxy() = def and + ( + src instanceof ExtensionMethod and not def instanceof ExtensionMethod + or + def instanceof ExtensionMethod and not src instanceof ExtensionMethod + ) +} + +query predicate extensionIndex(ExtensionMethod m, int i, Type t) { + m.fromSource() and + m.getExtensionReceiverParameterIndex() = i and + m.getExtendedType() = t and + m.getParameter(i).getType() = t +} diff --git a/java/ql/test/kotlin/library-tests/methods/methods3.kt b/java/ql/test/kotlin/library-tests/methods/methods3.kt index fdd759a7840..120a5339a5a 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods3.kt +++ b/java/ql/test/kotlin/library-tests/methods/methods3.kt @@ -1,7 +1,7 @@ package foo.bar -fun Int.fooBarTopLevelMethodExt(x: Int) {} +fun String.fooBarTopLevelMethodExt(x: Int = 1) {} class Class3 { - fun Int.fooBarTopLevelMethodExt(x: Int) {} + fun String.fooBarMethodExt(x: Int = 1) {} } diff --git a/java/ql/test/kotlin/library-tests/methods/parameters.expected b/java/ql/test/kotlin/library-tests/methods/parameters.expected index 4475aeba459..d4b3a2e2411 100644 --- a/java/ql/test/kotlin/library-tests/methods/parameters.expected +++ b/java/ql/test/kotlin/library-tests/methods/parameters.expected @@ -32,10 +32,19 @@ | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:34:4:39 | y | 1 | | methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:27:8:32 | x | 0 | | methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:35:8:40 | y | 1 | -| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | methods3.kt:3:5:3:7 | | 0 | -| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | methods3.kt:3:33:3:38 | x | 1 | -| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | methods3.kt:6:9:6:11 | | 0 | -| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | methods3.kt:6:37:6:42 | x | 1 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt | methods3.kt:3:5:3:10 | | 0 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt | methods3.kt:3:36:3:45 | x | 1 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | methods3.kt:3:1:3:49 | p0 | 0 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | methods3.kt:3:1:3:49 | p1 | 1 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | methods3.kt:3:1:3:49 | p2 | 2 | +| methods3.kt:3:1:3:49 | fooBarTopLevelMethodExt$default | methods3.kt:3:1:3:49 | p3 | 3 | +| methods3.kt:6:5:6:45 | fooBarMethodExt | methods3.kt:6:9:6:14 | | 0 | +| methods3.kt:6:5:6:45 | fooBarMethodExt | methods3.kt:6:32:6:41 | x | 1 | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | methods3.kt:6:5:6:45 | p0 | 0 | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | methods3.kt:6:5:6:45 | p1 | 1 | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | methods3.kt:6:5:6:45 | p2 | 2 | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | methods3.kt:6:5:6:45 | p3 | 3 | +| methods3.kt:6:5:6:45 | fooBarMethodExt$default | methods3.kt:6:5:6:45 | p4 | 4 | | methods4.kt:7:5:7:34 | m | methods4.kt:7:11:7:29 | x | 0 | | methods5.kt:5:3:5:27 | a | methods5.kt:5:13:5:18 | i | 0 | | methods5.kt:9:3:9:32 | f1 | methods5.kt:9:12:9:17 | | 0 | diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected index cdde306d74f..045fdb6d21c 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected @@ -3,18 +3,22 @@ | modifiers.kt:2:5:2:21 | a | Field | final | | modifiers.kt:2:5:2:21 | a | Field | private | | modifiers.kt:2:5:2:21 | a | Property | private | +| modifiers.kt:2:13:2:21 | getA$private | Method | final | | modifiers.kt:2:13:2:21 | getA$private | Method | private | | modifiers.kt:3:5:3:23 | b | Field | final | | modifiers.kt:3:5:3:23 | b | Field | private | | modifiers.kt:3:5:3:23 | b | Property | protected | +| modifiers.kt:3:15:3:23 | getB | Method | final | | modifiers.kt:3:15:3:23 | getB | Method | protected | | modifiers.kt:4:5:4:22 | c | Field | final | | modifiers.kt:4:5:4:22 | c | Field | private | | modifiers.kt:4:5:4:22 | c | Property | internal | +| modifiers.kt:4:14:4:22 | getC$main | Method | final | | modifiers.kt:4:14:4:22 | getC$main | Method | internal | | modifiers.kt:5:5:5:34 | d | Field | final | | modifiers.kt:5:5:5:34 | d | Field | private | | modifiers.kt:5:5:5:34 | d | Property | public | +| modifiers.kt:5:5:5:34 | getD | Method | final | | modifiers.kt:5:5:5:34 | getD | Method | public | | modifiers.kt:7:5:9:5 | Nested | Class | final | | modifiers.kt:7:5:9:5 | Nested | Class | protected | @@ -22,29 +26,38 @@ | modifiers.kt:8:9:8:29 | e | Field | final | | modifiers.kt:8:9:8:29 | e | Field | private | | modifiers.kt:8:9:8:29 | e | Property | public | +| modifiers.kt:8:16:8:29 | getE | Method | final | | modifiers.kt:8:16:8:29 | getE | Method | public | +| modifiers.kt:11:5:15:5 | fn1 | Method | final | | modifiers.kt:11:5:15:5 | fn1 | Method | public | | modifiers.kt:12:16:14:9 | | Constructor | public | | modifiers.kt:12:16:14:9 | new Object(...) { ... } | AnonymousClass | final | | modifiers.kt:12:16:14:9 | new Object(...) { ... } | AnonymousClass | private | | modifiers.kt:12:16:14:9 | new Object(...) { ... } | LocalClass | final | | modifiers.kt:12:16:14:9 | new Object(...) { ... } | LocalClass | private | +| modifiers.kt:13:13:13:23 | fn | Method | final | | modifiers.kt:13:13:13:23 | fn | Method | public | +| modifiers.kt:17:5:20:5 | fn2 | Method | final | | modifiers.kt:17:5:20:5 | fn2 | Method | public | | modifiers.kt:18:9:18:24 | | Constructor | public | | modifiers.kt:18:9:18:24 | | LocalClass | final | | modifiers.kt:18:9:18:24 | | LocalClass | private | +| modifiers.kt:18:9:18:24 | fnLocal | Method | final | | modifiers.kt:18:9:18:24 | fnLocal | Method | public | +| modifiers.kt:22:5:24:5 | fn3 | Method | final | | modifiers.kt:22:5:24:5 | fn3 | Method | public | | modifiers.kt:23:9:23:27 | localClass | Constructor | public | | modifiers.kt:23:9:23:27 | localClass | LocalClass | final | | modifiers.kt:23:9:23:27 | localClass | LocalClass | private | +| modifiers.kt:26:12:26:46 | fn4 | Method | final | | modifiers.kt:26:12:26:46 | fn4 | Method | inline | | modifiers.kt:26:12:26:46 | fn4 | Method | public | | modifiers.kt:26:20:26:41 | f | Parameter | noinline | +| modifiers.kt:27:12:27:49 | fn5 | Method | final | | modifiers.kt:27:12:27:49 | fn5 | Method | inline | | modifiers.kt:27:12:27:49 | fn5 | Method | public | | modifiers.kt:27:20:27:44 | f | Parameter | crossinline | +| modifiers.kt:28:12:28:39 | fn6 | Method | final | | modifiers.kt:28:12:28:39 | fn6 | Method | inline | | modifiers.kt:28:12:28:39 | fn6 | Method | public | | modifiers.kt:28:17:28:25 | T | TypeVariable | reified | @@ -57,6 +70,7 @@ | modifiers.kt:31:1:33:1 | Y | ParameterizedType | public | | modifiers.kt:31:9:31:13 | T1 | TypeVariable | in | | modifiers.kt:31:16:31:21 | T2 | TypeVariable | out | +| modifiers.kt:32:5:32:32 | foo | Method | final | | modifiers.kt:32:5:32:32 | foo | Method | public | | modifiers.kt:35:1:41:1 | LateInit | Class | final | | modifiers.kt:35:1:41:1 | LateInit | Class | public | @@ -64,7 +78,10 @@ | modifiers.kt:36:5:36:40 | test0 | Field | private | | modifiers.kt:36:5:36:40 | test0 | Property | lateinit | | modifiers.kt:36:5:36:40 | test0 | Property | private | +| modifiers.kt:36:22:36:40 | getTest0$private | Method | final | | modifiers.kt:36:22:36:40 | getTest0$private | Method | private | +| modifiers.kt:36:22:36:40 | setTest0$private | Method | final | | modifiers.kt:36:22:36:40 | setTest0$private | Method | private | +| modifiers.kt:38:5:40:5 | fn | Method | final | | modifiers.kt:38:5:40:5 | fn | Method | public | -| modifiers.kt:39:9:39:36 | LateInit test1 | LocalVariableDecl | lateinit | +| modifiers.kt:39:22:39:26 | LateInit test1 | LocalVariableDecl | lateinit | diff --git a/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected b/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected index af62c3e412e..46fd70318ad 100644 --- a/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/operator-overloads/PrintAst.expected @@ -59,7 +59,7 @@ test.kt: # 10| 0: [TypeAccess] int # 10| 5: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... -# 10| 0: [StringLiteral] +# 10| 0: [StringLiteral] "" # 11| 3: [ExtensionMethod] set # 11| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -73,7 +73,7 @@ test.kt: # 11| 0: [TypeAccess] int # 11| 5: [BlockStmt] { ... } # 11| 0: [ReturnStmt] return ... -# 11| 0: [StringLiteral] +# 11| 0: [StringLiteral] "" # 12| 4: [ExtensionMethod] set # 12| 3: [TypeAccess] String #-----| 4: (Parameters) @@ -85,7 +85,7 @@ test.kt: # 12| 0: [TypeAccess] C # 12| 5: [BlockStmt] { ... } # 12| 0: [ReturnStmt] return ... -# 12| 0: [StringLiteral] +# 12| 0: [StringLiteral] "" # 15| 2: [Class] C # 15| 1: [Constructor] C # 15| 5: [BlockStmt] { ... } @@ -100,4 +100,4 @@ test.kt: # 16| 0: [TypeAccess] int # 16| 5: [BlockStmt] { ... } # 16| 0: [ReturnStmt] return ... -# 16| 0: [StringLiteral] +# 16| 0: [StringLiteral] "" diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected index a769bc397ee..13bd441dfcd 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected @@ -56,7 +56,7 @@ test.kt: # 184| 1: [ExprStmt] ; # 184| 0: [AssignExpr] ...=... # 184| 0: [VarAccess] p0 -# 184| 1: [StringLiteral] before-vararg-default sunk +# 184| 1: [StringLiteral] "before-vararg-default sunk" # 184| 1: [IfStmt] if (...) # 184| 0: [EQExpr] ... == ... # 184| 0: [AndBitwiseExpr] ... & ... @@ -68,8 +68,8 @@ test.kt: # 184| 0: [VarAccess] p1 # 184| 1: [ArrayCreationExpr] new String[] # 184| -2: [ArrayInit] {...} -# 184| 0: [StringLiteral] first-vararg-default sunk -# 184| 1: [StringLiteral] second-vararg-default sunk +# 184| 0: [StringLiteral] "first-vararg-default sunk" +# 184| 1: [StringLiteral] "second-vararg-default sunk" # 184| -1: [TypeAccess] String # 184| 0: [IntegerLiteral] 2 # 184| 2: [IfStmt] if (...) @@ -81,7 +81,7 @@ test.kt: # 184| 1: [ExprStmt] ; # 184| 0: [AssignExpr] ...=... # 184| 0: [VarAccess] p2 -# 184| 1: [StringLiteral] after-vararg-default sunk +# 184| 1: [StringLiteral] "after-vararg-default sunk" # 184| 3: [ReturnStmt] return ... # 184| 0: [MethodAccess] varargsTest(...) # 184| -1: [TypeAccess] TestKt @@ -102,7 +102,7 @@ test.kt: # 192| 1: [ExprStmt] ; # 192| 0: [MethodAccess] varargsTest$default(...) # 192| -1: [TypeAccess] TestKt -# 192| 0: [StringLiteral] no-varargs-before, no-z-parameter sunk +# 192| 0: [StringLiteral] "no-varargs-before, no-z-parameter sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -110,32 +110,32 @@ test.kt: # 193| 2: [ExprStmt] ; # 193| 0: [MethodAccess] varargsTest$default(...) # 193| -1: [TypeAccess] TestKt -# 193| 0: [StringLiteral] no-varargs-before sunk +# 193| 0: [StringLiteral] "no-varargs-before sunk" # 1| 1: [NullLiteral] null -# 193| 2: [StringLiteral] no-varargs-after sunk +# 193| 2: [StringLiteral] "no-varargs-after sunk" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 194| 3: [ExprStmt] ; # 194| 0: [MethodAccess] varargsTest(...) # 194| -1: [TypeAccess] TestKt -# 194| 0: [StringLiteral] one-vararg-before sunk -# 194| 1: [StringLiteral] one-vararg sunk -# 194| 2: [StringLiteral] one-vararg-after sunk +# 194| 0: [StringLiteral] "one-vararg-before sunk" +# 194| 1: [StringLiteral] "one-vararg sunk" +# 194| 2: [StringLiteral] "one-vararg-after sunk" # 195| 4: [ExprStmt] ; # 195| 0: [MethodAccess] varargsTest(...) # 195| -1: [TypeAccess] TestKt -# 195| 0: [StringLiteral] two-varargs-before sunk -# 195| 1: [StringLiteral] two-vararg-first sunk -# 195| 2: [StringLiteral] two-vararg-second sunk -# 195| 3: [StringLiteral] two-varargs-after sunk +# 195| 0: [StringLiteral] "two-varargs-before sunk" +# 195| 1: [StringLiteral] "two-vararg-first sunk" +# 195| 2: [StringLiteral] "two-vararg-second sunk" +# 195| 3: [StringLiteral] "two-varargs-after sunk" # 196| 5: [ExprStmt] ; # 196| 0: [MethodAccess] varargsTest$default(...) # 196| -1: [TypeAccess] TestKt -# 196| 0: [StringLiteral] no-z-parmeter sunk +# 196| 0: [StringLiteral] "no-z-parmeter sunk" # 196| 1: [ArrayCreationExpr] new String[] # 196| -2: [ArrayInit] {...} -# 196| 0: [StringLiteral] no-z-parameter first vararg sunk -# 196| 1: [StringLiteral] no-z-parameter second vararg sunk +# 196| 0: [StringLiteral] "no-z-parameter first vararg sunk" +# 196| 1: [StringLiteral] "no-z-parameter second vararg sunk" # 196| -1: [TypeAccess] String # 196| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -182,7 +182,7 @@ test.kt: # 199| 1: [ExprStmt] ; # 199| 0: [AssignExpr] ...=... # 199| 0: [VarAccess] p0 -# 199| 1: [StringLiteral] before-vararg-default not sunk 2 +# 199| 1: [StringLiteral] "before-vararg-default not sunk 2" # 199| 1: [IfStmt] if (...) # 199| 0: [EQExpr] ... == ... # 199| 0: [AndBitwiseExpr] ... & ... @@ -194,8 +194,8 @@ test.kt: # 199| 0: [VarAccess] p1 # 199| 1: [ArrayCreationExpr] new String[] # 199| -2: [ArrayInit] {...} -# 199| 0: [StringLiteral] first-vararg-default sunk 2 -# 199| 1: [StringLiteral] second-vararg-default sunk 2 +# 199| 0: [StringLiteral] "first-vararg-default sunk 2" +# 199| 1: [StringLiteral] "second-vararg-default sunk 2" # 199| -1: [TypeAccess] String # 199| 0: [IntegerLiteral] 2 # 199| 2: [IfStmt] if (...) @@ -207,7 +207,7 @@ test.kt: # 199| 1: [ExprStmt] ; # 199| 0: [AssignExpr] ...=... # 199| 0: [VarAccess] p2 -# 199| 1: [StringLiteral] after-vararg-default not sunk 2 +# 199| 1: [StringLiteral] "after-vararg-default not sunk 2" # 199| 3: [ReturnStmt] return ... # 199| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 199| -1: [TypeAccess] TestKt @@ -228,7 +228,7 @@ test.kt: # 205| 1: [ExprStmt] ; # 205| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 205| -1: [TypeAccess] TestKt -# 205| 0: [StringLiteral] no-varargs-before, no-z-parameter not sunk 2 +# 205| 0: [StringLiteral] "no-varargs-before, no-z-parameter not sunk 2" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -236,32 +236,32 @@ test.kt: # 206| 2: [ExprStmt] ; # 206| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 206| -1: [TypeAccess] TestKt -# 206| 0: [StringLiteral] no-varargs-before not sunk 2 +# 206| 0: [StringLiteral] "no-varargs-before not sunk 2" # 1| 1: [NullLiteral] null -# 206| 2: [StringLiteral] no-varargs-after not sunk 2 +# 206| 2: [StringLiteral] "no-varargs-after not sunk 2" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 207| 3: [ExprStmt] ; # 207| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 207| -1: [TypeAccess] TestKt -# 207| 0: [StringLiteral] one-vararg-before not sunk 2 -# 207| 1: [StringLiteral] one-vararg sunk 2 -# 207| 2: [StringLiteral] one-vararg-after not sunk 2 +# 207| 0: [StringLiteral] "one-vararg-before not sunk 2" +# 207| 1: [StringLiteral] "one-vararg sunk 2" +# 207| 2: [StringLiteral] "one-vararg-after not sunk 2" # 208| 4: [ExprStmt] ; # 208| 0: [MethodAccess] varargsTestOnlySinkVarargs(...) # 208| -1: [TypeAccess] TestKt -# 208| 0: [StringLiteral] two-varargs-before not sunk 2 -# 208| 1: [StringLiteral] two-vararg-first sunk 2 -# 208| 2: [StringLiteral] two-vararg-second sunk 2 -# 208| 3: [StringLiteral] two-varargs-after not sunk 2 +# 208| 0: [StringLiteral] "two-varargs-before not sunk 2" +# 208| 1: [StringLiteral] "two-vararg-first sunk 2" +# 208| 2: [StringLiteral] "two-vararg-second sunk 2" +# 208| 3: [StringLiteral] "two-varargs-after not sunk 2" # 209| 5: [ExprStmt] ; # 209| 0: [MethodAccess] varargsTestOnlySinkVarargs$default(...) # 209| -1: [TypeAccess] TestKt -# 209| 0: [StringLiteral] no-z-parmeter not sunk 2 +# 209| 0: [StringLiteral] "no-z-parmeter not sunk 2" # 209| 1: [ArrayCreationExpr] new String[] # 209| -2: [ArrayInit] {...} -# 209| 0: [StringLiteral] no-z-parameter first vararg sunk 2 -# 209| 1: [StringLiteral] no-z-parameter second vararg sunk 2 +# 209| 0: [StringLiteral] "no-z-parameter first vararg sunk 2" +# 209| 1: [StringLiteral] "no-z-parameter second vararg sunk 2" # 209| -1: [TypeAccess] String # 209| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -310,7 +310,7 @@ test.kt: # 212| 1: [ExprStmt] ; # 212| 0: [AssignExpr] ...=... # 212| 0: [VarAccess] p0 -# 212| 1: [StringLiteral] before-vararg-default sunk 3 +# 212| 1: [StringLiteral] "before-vararg-default sunk 3" # 212| 1: [IfStmt] if (...) # 212| 0: [EQExpr] ... == ... # 212| 0: [AndBitwiseExpr] ... & ... @@ -322,8 +322,8 @@ test.kt: # 212| 0: [VarAccess] p1 # 212| 1: [ArrayCreationExpr] new String[] # 212| -2: [ArrayInit] {...} -# 212| 0: [StringLiteral] first-vararg-default not sunk 3 -# 212| 1: [StringLiteral] second-vararg-default not sunk 3 +# 212| 0: [StringLiteral] "first-vararg-default not sunk 3" +# 212| 1: [StringLiteral] "second-vararg-default not sunk 3" # 212| -1: [TypeAccess] String # 212| 0: [IntegerLiteral] 2 # 212| 2: [IfStmt] if (...) @@ -335,7 +335,7 @@ test.kt: # 212| 1: [ExprStmt] ; # 212| 0: [AssignExpr] ...=... # 212| 0: [VarAccess] p2 -# 212| 1: [StringLiteral] after-vararg-default sunk 3 +# 212| 1: [StringLiteral] "after-vararg-default sunk 3" # 212| 3: [ReturnStmt] return ... # 212| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 212| -1: [TypeAccess] TestKt @@ -356,7 +356,7 @@ test.kt: # 219| 1: [ExprStmt] ; # 219| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 219| -1: [TypeAccess] TestKt -# 219| 0: [StringLiteral] no-varargs-before, no-z-parameter sunk 3 +# 219| 0: [StringLiteral] "no-varargs-before, no-z-parameter sunk 3" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -364,32 +364,32 @@ test.kt: # 220| 2: [ExprStmt] ; # 220| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 220| -1: [TypeAccess] TestKt -# 220| 0: [StringLiteral] no-varargs-before sunk 3 +# 220| 0: [StringLiteral] "no-varargs-before sunk 3" # 1| 1: [NullLiteral] null -# 220| 2: [StringLiteral] no-varargs-after sunk 3 +# 220| 2: [StringLiteral] "no-varargs-after sunk 3" # 1| 3: [IntegerLiteral] 5 # 1| 4: [NullLiteral] null # 221| 3: [ExprStmt] ; # 221| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 221| -1: [TypeAccess] TestKt -# 221| 0: [StringLiteral] one-vararg-before sunk 3 -# 221| 1: [StringLiteral] one-vararg not sunk 3 -# 221| 2: [StringLiteral] one-vararg-after sunk 3 +# 221| 0: [StringLiteral] "one-vararg-before sunk 3" +# 221| 1: [StringLiteral] "one-vararg not sunk 3" +# 221| 2: [StringLiteral] "one-vararg-after sunk 3" # 222| 4: [ExprStmt] ; # 222| 0: [MethodAccess] varargsTestOnlySinkRegularArgs(...) # 222| -1: [TypeAccess] TestKt -# 222| 0: [StringLiteral] two-varargs-before sunk 3 -# 222| 1: [StringLiteral] two-vararg-first not sunk 3 -# 222| 2: [StringLiteral] two-vararg-second not sunk 3 -# 222| 3: [StringLiteral] two-varargs-after sunk 3 +# 222| 0: [StringLiteral] "two-varargs-before sunk 3" +# 222| 1: [StringLiteral] "two-vararg-first not sunk 3" +# 222| 2: [StringLiteral] "two-vararg-second not sunk 3" +# 222| 3: [StringLiteral] "two-varargs-after sunk 3" # 223| 5: [ExprStmt] ; # 223| 0: [MethodAccess] varargsTestOnlySinkRegularArgs$default(...) # 223| -1: [TypeAccess] TestKt -# 223| 0: [StringLiteral] no-z-parmeter sunk 3 +# 223| 0: [StringLiteral] "no-z-parmeter sunk 3" # 223| 1: [ArrayCreationExpr] new String[] # 223| -2: [ArrayInit] {...} -# 223| 0: [StringLiteral] no-z-parameter first vararg not sunk 3 -# 223| 1: [StringLiteral] no-z-parameter second vararg not sunk 3 +# 223| 0: [StringLiteral] "no-z-parameter first vararg not sunk 3" +# 223| 1: [StringLiteral] "no-z-parameter second vararg not sunk 3" # 223| -1: [TypeAccess] String # 223| 0: [IntegerLiteral] 2 # 1| 2: [NullLiteral] null @@ -403,15 +403,15 @@ test.kt: # 233| 0: [TypeAccess] Unit # 233| 1: [ClassInstanceExpr] new VarargsConstructorTest(...) # 233| -3: [TypeAccess] VarargsConstructorTest -# 233| 0: [StringLiteral] varargs constructor test sunk +# 233| 0: [StringLiteral] "varargs constructor test sunk" # 234| 1: [ExprStmt] ; # 234| 0: [ImplicitCoercionToUnitExpr] # 234| 0: [TypeAccess] Unit # 234| 1: [ClassInstanceExpr] new VarargsConstructorTest(...) # 234| -3: [TypeAccess] VarargsConstructorTest -# 234| 0: [StringLiteral] varargs constructor test sunk 2 -# 234| 1: [StringLiteral] varargs constructor test not sunk 1 -# 234| 2: [StringLiteral] varargs constructor test not sunk 2 +# 234| 0: [StringLiteral] "varargs constructor test sunk 2" +# 234| 1: [StringLiteral] "varargs constructor test not sunk 1" +# 234| 2: [StringLiteral] "varargs constructor test not sunk 2" # 3| 2: [Class] TestMember # 3| 1: [Constructor] TestMember # 3| 5: [BlockStmt] { ... } @@ -466,7 +466,7 @@ test.kt: # 5| 1: [ExprStmt] ; # 5| 0: [AssignExpr] ...=... # 5| 0: [VarAccess] p3 -# 5| 1: [StringLiteral] hello world +# 5| 1: [StringLiteral] "hello world" # 5| 2: [ReturnStmt] return ... # 5| 0: [MethodAccess] f(...) # 5| -1: [VarAccess] p0 @@ -480,7 +480,7 @@ test.kt: # 10| 0: [MethodAccess] f$default(...) # 10| -1: [TypeAccess] TestMember # 10| 0: [ThisAccess] this -# 10| 1: [StringLiteral] member sunk +# 10| 1: [StringLiteral] "member sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -489,17 +489,17 @@ test.kt: # 11| 0: [MethodAccess] f$default(...) # 11| -1: [TypeAccess] TestMember # 11| 0: [ThisAccess] this -# 11| 1: [StringLiteral] member sunk fp -# 11| 2: [StringLiteral] member sunk 2 +# 11| 1: [StringLiteral] "member sunk fp" +# 11| 2: [StringLiteral] "member sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 12| 2: [ExprStmt] ; # 12| 0: [MethodAccess] f(...) # 12| -1: [ThisAccess] this -# 12| 0: [StringLiteral] not sunk -# 12| 1: [StringLiteral] member sunk 3 -# 12| 2: [StringLiteral] not sunk +# 12| 0: [StringLiteral] "not sunk" +# 12| 1: [StringLiteral] "member sunk 3" +# 12| 2: [StringLiteral] "not sunk" # 17| 3: [Class] TestExtensionMember # 17| 1: [Constructor] TestExtensionMember # 17| 5: [BlockStmt] { ... } @@ -525,13 +525,13 @@ test.kt: # 21| 0: [MethodAccess] sink(...) # 21| -1: [TypeAccess] TestKt # 21| 0: [VarAccess] y -# 19| 3: [Method] f$default +# 19| 3: [ExtensionMethod] f$default # 19| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 19| 0: [Parameter] p0 -# 19| 0: [TypeAccess] String -# 19| 1: [Parameter] p1 # 19| 0: [TypeAccess] TestExtensionMember +# 19| 1: [Parameter] p1 +# 19| 0: [TypeAccess] String # 19| 2: [Parameter] p2 # 19| 0: [TypeAccess] String # 19| 3: [Parameter] p3 @@ -562,11 +562,11 @@ test.kt: # 19| 1: [ExprStmt] ; # 19| 0: [AssignExpr] ...=... # 19| 0: [VarAccess] p4 -# 19| 1: [StringLiteral] hello world +# 19| 1: [StringLiteral] "hello world" # 19| 2: [ReturnStmt] return ... # 19| 0: [MethodAccess] f(...) -# 19| -1: [VarAccess] p1 -# 19| 0: [VarAccess] p0 +# 19| -1: [VarAccess] p0 +# 19| 0: [ExtensionReceiverAccess] this # 19| 1: [VarAccess] p2 # 19| 2: [VarAccess] p3 # 19| 3: [VarAccess] p4 @@ -579,9 +579,9 @@ test.kt: # 25| 0: [ExprStmt] ; # 25| 0: [MethodAccess] f$default(...) # 25| -1: [TypeAccess] TestExtensionMember -# 25| 0: [VarAccess] sunk -# 25| 1: [ThisAccess] this -# 25| 2: [StringLiteral] extension sunk +# 25| 0: [ThisAccess] this +# 25| 1: [VarAccess] sunk +# 25| 2: [StringLiteral] "extension sunk" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 1 @@ -589,10 +589,10 @@ test.kt: # 26| 1: [ExprStmt] ; # 26| 0: [MethodAccess] f$default(...) # 26| -1: [TypeAccess] TestExtensionMember -# 26| 0: [VarAccess] sunk -# 26| 1: [ThisAccess] this -# 26| 2: [StringLiteral] extension sunk fp -# 26| 3: [StringLiteral] extension sunk 2 +# 26| 0: [ThisAccess] this +# 26| 1: [VarAccess] sunk +# 26| 2: [StringLiteral] "extension sunk fp" +# 26| 3: [StringLiteral] "extension sunk 2" # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 3 # 1| 6: [NullLiteral] null @@ -600,15 +600,17 @@ test.kt: # 27| 0: [MethodAccess] f(...) # 27| -1: [ThisAccess] this # 27| 0: [VarAccess] sunk -# 27| 1: [StringLiteral] not sunk -# 27| 2: [StringLiteral] extension sunk 3 -# 27| 3: [StringLiteral] not sunk +# 27| 1: [StringLiteral] "not sunk" +# 27| 2: [StringLiteral] "extension sunk 3" +# 27| 3: [StringLiteral] "not sunk" # 32| 4: [Class] TestStaticMember # 32| 1: [Constructor] TestStaticMember # 32| 5: [BlockStmt] { ... } # 32| 0: [SuperConstructorInvocationStmt] super(...) # 32| 1: [BlockStmt] { ... } # 34| 2: [Method] f +#-----| 1: (Annotations) +# 34| 1: [Annotation] JvmStatic # 34| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 34| 0: [Parameter] x @@ -655,7 +657,7 @@ test.kt: # 34| 1: [ExprStmt] ; # 34| 0: [AssignExpr] ...=... # 34| 0: [VarAccess] p2 -# 34| 1: [StringLiteral] hello world +# 34| 1: [StringLiteral] "hello world" # 34| 2: [ReturnStmt] return ... # 34| 0: [MethodAccess] f(...) # 34| -1: [TypeAccess] TestStaticMember @@ -668,7 +670,7 @@ test.kt: # 39| 0: [ExprStmt] ; # 39| 0: [MethodAccess] f$default(...) # 39| -1: [TypeAccess] TestStaticMember -# 39| 0: [StringLiteral] static sunk +# 39| 0: [StringLiteral] "static sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -676,17 +678,17 @@ test.kt: # 40| 1: [ExprStmt] ; # 40| 0: [MethodAccess] f$default(...) # 40| -1: [TypeAccess] TestStaticMember -# 40| 0: [StringLiteral] static sunk fp -# 40| 1: [StringLiteral] static sunk 2 +# 40| 0: [StringLiteral] "static sunk fp" +# 40| 1: [StringLiteral] "static sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null # 41| 2: [ExprStmt] ; # 41| 0: [MethodAccess] f(...) # 41| -1: [TypeAccess] TestStaticMember -# 41| 0: [StringLiteral] not sunk -# 41| 1: [StringLiteral] static sunk 3 -# 41| 2: [StringLiteral] not sunk +# 41| 0: [StringLiteral] "not sunk" +# 41| 1: [StringLiteral] "static sunk 3" +# 41| 2: [StringLiteral] "not sunk" # 46| 5: [Class] ExtendMe # 46| 1: [Constructor] ExtendMe # 46| 5: [BlockStmt] { ... } @@ -729,13 +731,13 @@ test.kt: # 57| 0: [MethodAccess] sink(...) # 57| -1: [TypeAccess] TestKt # 57| 0: [VarAccess] y -# 56| 4: [Method] test$default +# 56| 4: [ExtensionMethod] test$default # 56| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 56| 0: [Parameter] p0 -# 56| 0: [TypeAccess] ExtendMe -# 56| 1: [Parameter] p1 # 56| 0: [TypeAccess] TestReceiverReferences +# 56| 1: [Parameter] p1 +# 56| 0: [TypeAccess] ExtendMe # 56| 2: [Parameter] p2 # 56| 0: [TypeAccess] String # 56| 3: [Parameter] p3 @@ -759,7 +761,7 @@ test.kt: # 56| 1: [MethodAccess] f(...) # 56| -1: [VarAccess] p0 # 56| 0: [MethodAccess] g(...) -# 56| -1: [VarAccess] p1 +# 56| -1: [VarAccess] p0 # 56| 0: [VarAccess] p2 # 56| 1: [IfStmt] if (...) # 56| 0: [EQExpr] ... == ... @@ -770,11 +772,11 @@ test.kt: # 56| 1: [ExprStmt] ; # 56| 0: [AssignExpr] ...=... # 56| 0: [VarAccess] p4 -# 56| 1: [StringLiteral] hello world +# 56| 1: [StringLiteral] "hello world" # 56| 2: [ReturnStmt] return ... # 56| 0: [MethodAccess] test(...) -# 56| -1: [VarAccess] p1 -# 56| 0: [VarAccess] p0 +# 56| -1: [VarAccess] p0 +# 56| 0: [ExtensionReceiverAccess] this # 56| 1: [VarAccess] p2 # 56| 2: [VarAccess] p3 # 56| 3: [VarAccess] p4 @@ -787,9 +789,9 @@ test.kt: # 61| 0: [ExprStmt] ; # 61| 0: [MethodAccess] test$default(...) # 61| -1: [TypeAccess] TestReceiverReferences -# 61| 0: [VarAccess] t -# 61| 1: [ThisAccess] this -# 61| 2: [StringLiteral] receiver refs sunk +# 61| 0: [ThisAccess] this +# 61| 1: [VarAccess] t +# 61| 2: [StringLiteral] "receiver refs sunk" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 1 @@ -797,10 +799,10 @@ test.kt: # 62| 1: [ExprStmt] ; # 62| 0: [MethodAccess] test$default(...) # 62| -1: [TypeAccess] TestReceiverReferences -# 62| 0: [VarAccess] t -# 62| 1: [ThisAccess] this -# 62| 2: [StringLiteral] receiver refs sunk fp -# 62| 3: [StringLiteral] receiver refs sunk 2 +# 62| 0: [ThisAccess] this +# 62| 1: [VarAccess] t +# 62| 2: [StringLiteral] "receiver refs sunk fp" +# 62| 3: [StringLiteral] "receiver refs sunk 2" # 1| 4: [NullLiteral] null # 1| 5: [IntegerLiteral] 3 # 1| 6: [NullLiteral] null @@ -808,9 +810,9 @@ test.kt: # 63| 0: [MethodAccess] test(...) # 63| -1: [ThisAccess] this # 63| 0: [VarAccess] t -# 63| 1: [StringLiteral] not sunk -# 63| 2: [StringLiteral] receiver refs sunk 3 -# 63| 3: [StringLiteral] not sunk +# 63| 1: [StringLiteral] "not sunk" +# 63| 2: [StringLiteral] "receiver refs sunk 3" +# 63| 3: [StringLiteral] "not sunk" # 68| 7: [Class] TestConstructor # 68| 1: [Constructor] TestConstructor #-----| 4: (Parameters) @@ -859,7 +861,7 @@ test.kt: # 68| 1: [ExprStmt] ; # 68| 0: [AssignExpr] ...=... # 68| 0: [VarAccess] p2 -# 68| 1: [StringLiteral] hello world +# 68| 1: [StringLiteral] "hello world" # 68| 2: [ThisConstructorInvocationStmt] this(...) # 68| 0: [VarAccess] p0 # 68| 1: [VarAccess] p1 @@ -872,7 +874,7 @@ test.kt: # 75| 0: [TypeAccess] Unit # 75| 1: [ClassInstanceExpr] new TestConstructor(...) # 75| -3: [TypeAccess] TestConstructor -# 75| 0: [StringLiteral] constructor sunk +# 75| 0: [StringLiteral] "constructor sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -882,8 +884,8 @@ test.kt: # 76| 0: [TypeAccess] Unit # 76| 1: [ClassInstanceExpr] new TestConstructor(...) # 76| -3: [TypeAccess] TestConstructor -# 76| 0: [StringLiteral] constructor sunk fp -# 76| 1: [StringLiteral] constructor sunk 2 +# 76| 0: [StringLiteral] "constructor sunk fp" +# 76| 1: [StringLiteral] "constructor sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null @@ -892,9 +894,9 @@ test.kt: # 77| 0: [TypeAccess] Unit # 77| 1: [ClassInstanceExpr] new TestConstructor(...) # 77| -3: [TypeAccess] TestConstructor -# 77| 0: [StringLiteral] not sunk -# 77| 1: [StringLiteral] constructor sunk 3 -# 77| 2: [StringLiteral] not sunk +# 77| 0: [StringLiteral] "not sunk" +# 77| 1: [StringLiteral] "constructor sunk 3" +# 77| 2: [StringLiteral] "not sunk" # 82| 8: [Class] TestLocal # 82| 1: [Constructor] TestLocal # 82| 5: [BlockStmt] { ... } @@ -955,7 +957,7 @@ test.kt: # 86| 1: [ExprStmt] ; # 86| 0: [AssignExpr] ...=... # 86| 0: [VarAccess] p2 -# 86| 1: [StringLiteral] hello world +# 86| 1: [StringLiteral] "hello world" # 86| 2: [ReturnStmt] return ... # 86| 0: [MethodAccess] f(...) # 86| -1: [ClassInstanceExpr] new (...) @@ -974,7 +976,7 @@ test.kt: # 91| 0: [ExprStmt] ; # 91| 0: [MethodAccess] f$default(...) # 91| -1: [TypeAccess] -# 91| 0: [StringLiteral] local sunk +# 91| 0: [StringLiteral] "local sunk" # 1| 1: [NullLiteral] null # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 @@ -982,8 +984,8 @@ test.kt: # 92| 1: [ExprStmt] ; # 92| 0: [MethodAccess] f$default(...) # 92| -1: [TypeAccess] -# 92| 0: [StringLiteral] local sunk fp -# 92| 1: [StringLiteral] local sunk 2 +# 92| 0: [StringLiteral] "local sunk fp" +# 92| 1: [StringLiteral] "local sunk 2" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 3 # 1| 4: [NullLiteral] null @@ -991,9 +993,9 @@ test.kt: # 93| 0: [MethodAccess] f(...) # 93| -1: [ClassInstanceExpr] new (...) # 93| -3: [TypeAccess] Object -# 93| 0: [StringLiteral] not sunk -# 93| 1: [StringLiteral] local sunk 3 -# 93| 2: [StringLiteral] not sunk +# 93| 0: [StringLiteral] "not sunk" +# 93| 1: [StringLiteral] "local sunk 3" +# 93| 2: [StringLiteral] "not sunk" # 100| 9: [Class] TestLocalClass # 100| 1: [Constructor] TestLocalClass # 100| 5: [BlockStmt] { ... } @@ -1057,7 +1059,7 @@ test.kt: # 106| 1: [ExprStmt] ; # 106| 0: [AssignExpr] ...=... # 106| 0: [VarAccess] p3 -# 106| 1: [StringLiteral] hello world +# 106| 1: [StringLiteral] "hello world" # 106| 2: [ReturnStmt] return ... # 106| 0: [MethodAccess] f(...) # 106| -1: [VarAccess] p0 @@ -1071,7 +1073,7 @@ test.kt: # 111| 0: [MethodAccess] f$default(...) # 111| -1: [TypeAccess] EnclosingLocalClass # 111| 0: [ThisAccess] this -# 111| 1: [StringLiteral] local sunk +# 111| 1: [StringLiteral] "local sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -1080,17 +1082,17 @@ test.kt: # 112| 0: [MethodAccess] f$default(...) # 112| -1: [TypeAccess] EnclosingLocalClass # 112| 0: [ThisAccess] this -# 112| 1: [StringLiteral] local sunk fp -# 112| 2: [StringLiteral] local sunk 2 +# 112| 1: [StringLiteral] "local sunk fp" +# 112| 2: [StringLiteral] "local sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 113| 2: [ExprStmt] ; # 113| 0: [MethodAccess] f(...) # 113| -1: [ThisAccess] this -# 113| 0: [StringLiteral] not sunk -# 113| 1: [StringLiteral] local sunk 3 -# 113| 2: [StringLiteral] not sunk +# 113| 0: [StringLiteral] "not sunk" +# 113| 1: [StringLiteral] "local sunk 3" +# 113| 2: [StringLiteral] "not sunk" # 122| 10: [Class,GenericType,ParameterizedType] TestGeneric #-----| -2: (Generic Parameters) # 122| 0: [TypeVariable] T @@ -1168,7 +1170,7 @@ test.kt: # 129| 0: [MethodAccess] f$default(...) # 129| -1: [TypeAccess] TestGeneric<> # 129| 0: [VarAccess] tgs -# 129| 1: [StringLiteral] generic sunk +# 129| 1: [StringLiteral] "generic sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 1 @@ -1177,23 +1179,23 @@ test.kt: # 130| 0: [MethodAccess] f$default(...) # 130| -1: [TypeAccess] TestGeneric<> # 130| 0: [VarAccess] tcs -# 130| 1: [StringLiteral] generic sunk fp -# 130| 2: [StringLiteral] generic sunk 2 +# 130| 1: [StringLiteral] "generic sunk fp" +# 130| 2: [StringLiteral] "generic sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [IntegerLiteral] 3 # 1| 5: [NullLiteral] null # 131| 2: [ExprStmt] ; # 131| 0: [MethodAccess] f(...) # 131| -1: [VarAccess] tgs -# 131| 0: [StringLiteral] not sunk -# 131| 1: [StringLiteral] generic sunk 3 -# 131| 2: [StringLiteral] not sunk +# 131| 0: [StringLiteral] "not sunk" +# 131| 1: [StringLiteral] "generic sunk 3" +# 131| 2: [StringLiteral] "not sunk" # 132| 3: [ExprStmt] ; # 132| 0: [MethodAccess] f(...) # 132| -1: [VarAccess] tcs -# 132| 0: [StringLiteral] not sunk -# 132| 1: [StringLiteral] generic sunk 3 -# 132| 2: [StringLiteral] not sunk +# 132| 0: [StringLiteral] "not sunk" +# 132| 1: [StringLiteral] "generic sunk 3" +# 132| 2: [StringLiteral] "not sunk" # 135| 5: [Method] testReturn # 135| 3: [TypeAccess] T #-----| 4: (Parameters) @@ -1246,7 +1248,7 @@ test.kt: # 138| 0: [MethodAccess] testReturn$default(...) # 138| -1: [TypeAccess] TestGeneric<> # 138| 0: [VarAccess] tgs -# 138| 1: [StringLiteral] sunk return value +# 138| 1: [StringLiteral] "sunk return value" # 1| 2: [NullLiteral] null # 1| 3: [IntegerLiteral] 1 # 1| 4: [NullLiteral] null @@ -1381,7 +1383,7 @@ test.kt: # 150| 0: [MethodAccess] f$default(...) # 150| -1: [TypeAccess] TestGenericFunction<> # 150| 0: [VarAccess] inst -# 150| 1: [StringLiteral] generic function sunk +# 150| 1: [StringLiteral] "generic function sunk" # 1| 2: [NullLiteral] null # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null @@ -1393,8 +1395,8 @@ test.kt: # 151| 0: [MethodAccess] f$default(...) # 151| -1: [TypeAccess] TestGenericFunction<> # 151| 0: [VarAccess] inst -# 151| 1: [StringLiteral] generic function sunk fp -# 151| 2: [StringLiteral] generic function sunk 2 +# 151| 1: [StringLiteral] "generic function sunk fp" +# 151| 2: [StringLiteral] "generic function sunk 2" # 1| 3: [NullLiteral] null # 1| 4: [NullLiteral] null # 1| 5: [NullLiteral] null @@ -1612,7 +1614,7 @@ test.kt: # 171| -1: [ClassInstanceExpr] new TestGenericUsedWithinDefaultValue(...) # 171| -3: [TypeAccess] TestGenericUsedWithinDefaultValue # 171| 0: [TypeAccess] String -# 171| 0: [StringLiteral] Hello world +# 171| 0: [StringLiteral] "Hello world" # 171| 1: [ReturnStmt] return ... # 171| 0: [MethodAccess] f(...) # 171| -1: [VarAccess] p0 @@ -1662,7 +1664,7 @@ test.kt: # 179| 1: [ExprStmt] ; # 179| 0: [AssignExpr] ...=... # 179| 0: [VarAccess] p2 -# 179| 1: [StringLiteral] Hello world +# 179| 1: [StringLiteral] "Hello world" # 179| 1: [ReturnStmt] return ... # 179| 0: [MethodAccess] f(...) # 179| -1: [VarAccess] p0 diff --git a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected index 64fffd47586..9f4ece3d033 100644 --- a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected @@ -45,7 +45,7 @@ reflection.kt: # 50| -3: [TypeAccess] KProperty1 # 50| 0: [TypeAccess] String # 50| 1: [TypeAccess] Character -# 50| 0: [StringLiteral] abc +# 50| 0: [StringLiteral] "abc" # 51| 1: [ExprStmt] ; # 51| 0: [MethodAccess] println(...) # 51| -1: [TypeAccess] ConsoleKt @@ -78,7 +78,7 @@ reflection.kt: # 51| -1: [ThisAccess] this # 51| -3: [TypeAccess] KProperty0 # 51| 0: [TypeAccess] Character -# 51| 0: [StringLiteral] abcd +# 51| 0: [StringLiteral] "abcd" # 54| 3: [ExtensionMethod] ext1 #-----| 2: (Generic Parameters) # 54| 0: [TypeVariable] T2 @@ -118,7 +118,7 @@ reflection.kt: # 97| 0: [TypeAccess] String # 97| -2: [TypeAccess] String # 97| -1: [TypeAccess] ReflectionKt -# 97| 0: [StringLiteral] +# 97| 0: [StringLiteral] "" # 97| 1: [MemberRefExpr] ...::... # 97| -4: [AnonymousClass] new Function1>(...) { ... } # 97| 1: [Constructor] @@ -143,7 +143,7 @@ reflection.kt: # 98| -3: [TypeAccess] Unit # 98| -2: [TypeAccess] String # 98| -1: [TypeAccess] ReflectionKt -# 98| 0: [StringLiteral] +# 98| 0: [StringLiteral] "" # 98| 1: [MemberRefExpr] ...::... # 98| -4: [AnonymousClass] new Function1(...) { ... } # 98| 1: [Constructor] @@ -169,7 +169,7 @@ reflection.kt: # 99| 1: [TypeAccess] Integer # 99| -2: [TypeAccess] String # 99| -1: [TypeAccess] ReflectionKt -# 99| 0: [StringLiteral] +# 99| 0: [StringLiteral] "" # 99| 1: [MemberRefExpr] ...::... # 99| -4: [AnonymousClass] new Function1>(...) { ... } # 99| 1: [Constructor] @@ -534,7 +534,7 @@ reflection.kt: # 150| 0: [AddExpr] ... + ... # 150| 0: [VarAccess] x # 150| 1: [VarAccess] y -# 150| 20: [Method] extTakesOptionalParam$default +# 150| 20: [ExtensionMethod] extTakesOptionalParam$default # 150| 3: [TypeAccess] int #-----| 4: (Parameters) # 150| 0: [Parameter] p0 @@ -561,7 +561,7 @@ reflection.kt: # 150| 1: [ReturnStmt] return ... # 150| 0: [MethodAccess] extTakesOptionalParam(...) # 150| -1: [TypeAccess] ReflectionKt -# 150| 0: [VarAccess] p0 +# 150| 0: [ExtensionReceiverAccess] this # 150| 1: [VarAccess] p1 # 150| 2: [VarAccess] p2 # 152| 21: [Method] extensionAdaptedParams @@ -1026,7 +1026,7 @@ reflection.kt: # 24| 0: [ValueEQExpr] ... (value equals) ... # 24| 0: [MethodAccess] getName(...) # 24| -1: [VarAccess] it -# 24| 1: [StringLiteral] p3 +# 24| 1: [StringLiteral] "p3" # 24| -3: [TypeAccess] Function1,Boolean> # 24| 0: [TypeAccess] KCallable # 24| 1: [TypeAccess] Boolean @@ -1534,7 +1534,7 @@ reflection.kt: # 90| 1: [TypeAccess] T # 90| -2: [TypeAccess] String # 90| -1: [TypeAccess] ReflectionKt -# 90| 0: [StringLiteral] +# 90| 0: [StringLiteral] "" # 90| 1: [MemberRefExpr] ...::... # 90| -4: [AnonymousClass] new Function1>(...) { ... } # 90| 1: [Constructor] diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.expected b/java/ql/test/kotlin/library-tests/reflection/reflection.expected index e6a864b11a4..f2482a81ec1 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.expected +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.expected @@ -1,26 +1,26 @@ variableInitializerType -| reflection.kt:7:9:7:54 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:7:9:7:54 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:10:9:10:42 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///KProperty1.class:0:0:0:0 | KProperty1 | true | -| reflection.kt:10:9:10:42 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:13:9:13:53 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:13:9:13:53 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty$Getter.class:0:0:0:0 | Getter | true | -| reflection.kt:14:9:14:44 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:14:9:14:44 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:15:9:15:41 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///KProperty0.class:0:0:0:0 | KProperty0 | true | -| reflection.kt:15:9:15:41 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:17:9:17:49 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | true | -| reflection.kt:17:9:17:49 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:20:9:20:60 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:20:9:20:60 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty$Setter.class:0:0:0:0 | Setter | true | -| reflection.kt:21:9:21:50 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:21:9:21:50 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | -| reflection.kt:22:9:22:48 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | true | -| reflection.kt:22:9:22:48 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | -| reflection.kt:24:9:24:91 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///Function2.class:0:0:0:0 | Function2 | true | -| reflection.kt:24:9:24:91 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty.class:0:0:0:0 | KProperty | true | -| reflection.kt:116:9:116:44 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | -| reflection.kt:116:9:116:44 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:7:13:7:15 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:7:13:7:15 | KFunction ref | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:7:49:7:54 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:10:13:10:14 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///KProperty1.class:0:0:0:0 | KProperty1 | true | +| reflection.kt:10:13:10:14 | KProperty1 x0 | file:///KProperty1.class:0:0:0:0 | KProperty1 | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:13:13:13:14 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:13:13:13:14 | Getter x3 | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty1$Getter.class:0:0:0:0 | Getter | file:///KProperty$Getter.class:0:0:0:0 | Getter | true | +| reflection.kt:14:13:14:14 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:14:13:14:14 | KFunction x4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:14:38:14:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:15:13:15:14 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///KProperty0.class:0:0:0:0 | KProperty0 | true | +| reflection.kt:15:13:15:14 | KProperty0 x5 | file:///KProperty0.class:0:0:0:0 | KProperty0 | reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:17:13:17:14 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | true | +| reflection.kt:17:13:17:14 | KMutableProperty1 y0 | file:///KMutableProperty1.class:0:0:0:0 | KMutableProperty1 | reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:20:13:20:14 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:20:13:20:14 | Setter y3 | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty1$Setter.class:0:0:0:0 | Setter | file:///KMutableProperty$Setter.class:0:0:0:0 | Setter | true | +| reflection.kt:21:13:21:14 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:21:13:21:14 | KFunction y4 | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:21:44:21:50 | new Function2(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | +| reflection.kt:22:13:22:14 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | true | +| reflection.kt:22:13:22:14 | KMutableProperty0 y5 | file:///KMutableProperty0.class:0:0:0:0 | KMutableProperty0 | reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | file:///PropertyReference.class:0:0:0:0 | PropertyReference | true | +| reflection.kt:24:13:24:16 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///Function2.class:0:0:0:0 | Function2 | true | +| reflection.kt:24:13:24:16 | KProperty2 prop | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty2.class:0:0:0:0 | KProperty2 | file:///KProperty.class:0:0:0:0 | KProperty | true | +| reflection.kt:116:13:116:13 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///Function1.class:0:0:0:0 | Function1 | true | +| reflection.kt:116:13:116:13 | KFunction x | file:///KFunction.class:0:0:0:0 | KFunction | reflection.kt:116:40:116:44 | new Function1(...) { ... } | file:///FunctionReference.class:0:0:0:0 | FunctionReference | true | invocation | reflection.kt:8:17:8:24 | getName(...) | file:///KCallable.class:0:0:0:0 | getName | | reflection.kt:11:23:11:33 | get(...) | file:///KProperty1.class:0:0:0:0 | get | @@ -282,23 +282,58 @@ compGenerated | file:///LongRange.class:0:0:0:0 | forEach | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | +| reflection.kt:7:49:7:54 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:14:38:14:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:15:35:15:41 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:17:45:17:49 | new KMutableProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:21:44:21:50 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:22:42:22:48 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:24:46:24:64 | new Function1,Boolean>(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:33:9:33:23 | getP0 | Default property accessor | | reflection.kt:34:9:34:23 | getP1 | Default property accessor | | reflection.kt:34:9:34:23 | setP1 | Default property accessor | +| reflection.kt:50:13:50:28 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:51:13:51:28 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:60:17:60:32 | new Function2,Integer,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:61:17:61:34 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:62:17:62:34 | new Function1,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:63:17:63:36 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:64:17:64:34 | new Function1,String>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:65:17:65:36 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:67:17:67:32 | new KMutableProperty1,Integer>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:68:17:68:34 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:70:17:70:30 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:71:17:71:34 | new KProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:72:17:72:35 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:83:17:83:28 | getValue | Default property accessor | +| reflection.kt:90:18:90:24 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:97:14:97:21 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:98:14:98:17 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:99:14:99:29 | new Function1>(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:105:18:105:31 | getProp1 | Default property accessor | | reflection.kt:105:18:105:31 | setProp1 | Default property accessor | +| reflection.kt:109:17:109:27 | new KMutableProperty0(...) { ... } | The class around a local function, a lambda, or a function reference | +| reflection.kt:115:9:115:27 | | The class around a local function, a lambda, or a function reference | +| reflection.kt:116:40:116:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:126:9:126:13 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:126:9:126:13 | new Function0(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:131:1:131:50 | takesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:134:21:134:40 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:134:21:134:40 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:140:5:140:54 | takesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:144:21:144:41 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:144:21:144:41 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:145:32:145:70 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:145:32:145:70 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:150:1:150:60 | extTakesOptionalParam$default | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:153:21:153:44 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:153:21:153:44 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:154:33:154:61 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:154:33:154:61 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:157:1:157:49 | ConstructorOptional | Forwarder for Kotlin calls that need default arguments filling in | | reflection.kt:162:25:162:45 | | Declaring classes of adapter functions in Kotlin | +| reflection.kt:162:25:162:45 | new Function1(...) { ... } | The class around a local function, a lambda, or a function reference | propertyReferenceOverrides | reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | get | kotlin.reflect.KProperty1.get(Reflection.C) | | reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | invoke | kotlin.jvm.functions.Function1.invoke(Reflection.C) | diff --git a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected index 2edcd3755b6..9cb7aac3c0f 100644 --- a/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/stmts/PrintAst.expected @@ -163,12 +163,12 @@ stmts.kt: # 41| 2: [BlockStmt] { ... } # 41| 0: [LocalVariableDeclStmt] var ...; # 41| 1: [LocalVariableDeclExpr] v -# 41| 0: [MethodAccess] component1(...) +# 0| 0: [MethodAccess] component1(...) # 41| -1: [VarAccess] tmp3_loop_parameter # 41| 1: [LocalVariableDeclStmt] var ...; # 41| 1: [LocalVariableDeclExpr] i -# 41| 0: [MethodAccess] component2(...) -# 41| -1: [VarAccess] tmp3_loop_parameter +# 0| 0: [MethodAccess] component2(...) +# 0| -1: [VarAccess] tmp3_loop_parameter # 41| 2: [BlockStmt] { ... } # 42| 0: [ExprStmt] ; # 42| 0: [WhenExpr] when ... @@ -188,7 +188,7 @@ stmts.kt: # 48| 0: [ThrowStmt] throw ... # 48| 0: [ClassInstanceExpr] new Exception(...) # 48| -3: [TypeAccess] Exception -# 48| 0: [StringLiteral] Foo +# 48| 0: [StringLiteral] "Foo" # 50| 0: [CatchClause] catch (...) #-----| 0: (Single Local Variable Declaration) # 50| 0: [TypeAccess] Exception diff --git a/java/ql/test/kotlin/library-tests/stmts/exprs.expected b/java/ql/test/kotlin/library-tests/stmts/exprs.expected index 01631139da3..5f652fdb17c 100644 --- a/java/ql/test/kotlin/library-tests/stmts/exprs.expected +++ b/java/ql/test/kotlin/library-tests/stmts/exprs.expected @@ -1,3 +1,6 @@ +| stmts.kt:0:0:0:0 | component1(...) | MethodAccess | +| stmts.kt:0:0:0:0 | component2(...) | MethodAccess | +| stmts.kt:0:0:0:0 | tmp3_loop_parameter | VarAccess | | stmts.kt:2:1:20:1 | int | TypeAccess | | stmts.kt:2:20:2:25 | int | TypeAccess | | stmts.kt:2:28:2:33 | int | TypeAccess | @@ -21,9 +24,9 @@ | stmts.kt:14:13:14:13 | x | VarAccess | | stmts.kt:14:13:14:17 | ... < ... | LTExpr | | stmts.kt:14:17:14:17 | y | VarAccess | -| stmts.kt:15:5:15:13 | z | LocalVariableDeclExpr | +| stmts.kt:15:9:15:9 | z | LocalVariableDeclExpr | | stmts.kt:15:13:15:13 | 3 | IntegerLiteral | -| stmts.kt:17:5:17:58 | q2 | LocalVariableDeclExpr | +| stmts.kt:17:9:17:10 | q2 | LocalVariableDeclExpr | | stmts.kt:17:26:17:58 | true | BooleanLiteral | | stmts.kt:17:26:17:58 | when ... | WhenExpr | | stmts.kt:17:29:17:32 | true | BooleanLiteral | @@ -33,7 +36,7 @@ | stmts.kt:17:52:17:52 | z | VarAccess | | stmts.kt:17:52:17:56 | ...=... | AssignExpr | | stmts.kt:17:56:17:56 | 5 | IntegerLiteral | -| stmts.kt:18:5:18:56 | q3 | LocalVariableDeclExpr | +| stmts.kt:18:9:18:10 | q3 | LocalVariableDeclExpr | | stmts.kt:18:26:18:56 | true | BooleanLiteral | | stmts.kt:18:26:18:56 | when ... | WhenExpr | | stmts.kt:18:29:18:32 | true | BooleanLiteral | @@ -81,13 +84,10 @@ | stmts.kt:38:18:38:18 | y | VarAccess | | stmts.kt:38:18:38:24 | ... > ... | GTExpr | | stmts.kt:38:22:38:24 | 100 | IntegerLiteral | -| stmts.kt:41:11:41:11 | component1(...) | MethodAccess | | stmts.kt:41:11:41:11 | v | LocalVariableDeclExpr | -| stmts.kt:41:13:41:13 | component2(...) | MethodAccess | | stmts.kt:41:13:41:13 | i | LocalVariableDeclExpr | | stmts.kt:41:19:41:36 | tmp3_loop_parameter | LocalVariableDeclExpr | | stmts.kt:41:19:41:36 | tmp3_loop_parameter | VarAccess | -| stmts.kt:41:19:41:36 | tmp3_loop_parameter | VarAccess | | stmts.kt:41:20:41:20 | x | VarAccess | | stmts.kt:41:20:41:23 | rangeTo(...) | MethodAccess | | stmts.kt:41:20:41:36 | CollectionsKt | TypeAccess | @@ -101,7 +101,7 @@ | stmts.kt:46:1:56:1 | int | TypeAccess | | stmts.kt:48:15:48:30 | Exception | TypeAccess | | stmts.kt:48:15:48:30 | new Exception(...) | ClassInstanceExpr | -| stmts.kt:48:26:48:28 | Foo | StringLiteral | +| stmts.kt:48:26:48:28 | "Foo" | StringLiteral | | stmts.kt:50:12:50:23 | Exception | TypeAccess | | stmts.kt:50:12:50:23 | e | LocalVariableDeclExpr | | stmts.kt:51:16:51:16 | 1 | IntegerLiteral | diff --git a/java/ql/test/kotlin/library-tests/stmts/exprs.ql b/java/ql/test/kotlin/library-tests/stmts/exprs.ql index 6ded7c0026d..c2ae4f55ac7 100644 --- a/java/ql/test/kotlin/library-tests/stmts/exprs.ql +++ b/java/ql/test/kotlin/library-tests/stmts/exprs.ql @@ -1,4 +1,5 @@ import java from Expr e +where e.getFile().isSourceFile() select e, e.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/stmts/stmts.expected b/java/ql/test/kotlin/library-tests/stmts/stmts.expected index c1fae753f23..716bea1649a 100644 --- a/java/ql/test/kotlin/library-tests/stmts/stmts.expected +++ b/java/ql/test/kotlin/library-tests/stmts/stmts.expected @@ -15,17 +15,17 @@ enclosing | stmts.kt:12:5:14:18 | { ... } | stmts.kt:2:41:20:1 | { ... } | | stmts.kt:12:8:14:5 | { ... } | stmts.kt:12:5:14:18 | do ... while (...) | | stmts.kt:13:9:13:16 | return ... | stmts.kt:12:8:14:5 | { ... } | -| stmts.kt:15:5:15:13 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:17:5:17:58 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:5:17:58 | var ...; | -| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:5:17:58 | var ...; | +| stmts.kt:15:9:15:9 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:17:9:17:10 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:9:17:10 | var ...; | +| stmts.kt:17:26:17:58 | ... -> ... | stmts.kt:17:9:17:10 | var ...; | | stmts.kt:17:35:17:43 | { ... } | stmts.kt:17:26:17:58 | ... -> ... | | stmts.kt:17:37:17:37 | ; | stmts.kt:17:35:17:43 | { ... } | | stmts.kt:17:50:17:58 | { ... } | stmts.kt:17:26:17:58 | ... -> ... | | stmts.kt:17:52:17:52 | ; | stmts.kt:17:50:17:58 | { ... } | -| stmts.kt:18:5:18:56 | var ...; | stmts.kt:2:41:20:1 | { ... } | -| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:5:18:56 | var ...; | -| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:5:18:56 | var ...; | +| stmts.kt:18:9:18:10 | var ...; | stmts.kt:2:41:20:1 | { ... } | +| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:9:18:10 | var ...; | +| stmts.kt:18:26:18:56 | ... -> ... | stmts.kt:18:9:18:10 | var ...; | | stmts.kt:18:37:18:37 | ; | stmts.kt:18:26:18:56 | ... -> ... | | stmts.kt:18:52:18:52 | ; | stmts.kt:18:26:18:56 | ... -> ... | | stmts.kt:19:5:19:16 | return ... | stmts.kt:2:41:20:1 | { ... } | @@ -88,15 +88,15 @@ enclosing | stmts.kt:12:5:14:18 | { ... } | BlockStmt | | stmts.kt:12:8:14:5 | { ... } | BlockStmt | | stmts.kt:13:9:13:16 | return ... | ReturnStmt | -| stmts.kt:15:5:15:13 | var ...; | LocalVariableDeclStmt | -| stmts.kt:17:5:17:58 | var ...; | LocalVariableDeclStmt | +| stmts.kt:15:9:15:9 | var ...; | LocalVariableDeclStmt | +| stmts.kt:17:9:17:10 | var ...; | LocalVariableDeclStmt | | stmts.kt:17:26:17:58 | ... -> ... | WhenBranch | | stmts.kt:17:26:17:58 | ... -> ... | WhenBranch | | stmts.kt:17:35:17:43 | { ... } | BlockStmt | | stmts.kt:17:37:17:37 | ; | ExprStmt | | stmts.kt:17:50:17:58 | { ... } | BlockStmt | | stmts.kt:17:52:17:52 | ; | ExprStmt | -| stmts.kt:18:5:18:56 | var ...; | LocalVariableDeclStmt | +| stmts.kt:18:9:18:10 | var ...; | LocalVariableDeclStmt | | stmts.kt:18:26:18:56 | ... -> ... | WhenBranch | | stmts.kt:18:26:18:56 | ... -> ... | WhenBranch | | stmts.kt:18:37:18:37 | ; | ExprStmt | diff --git a/java/ql/test/kotlin/library-tests/trap/diags.expected b/java/ql/test/kotlin/library-tests/trap/diags.expected index 377b7fd0a99..a4a774de5f9 100644 --- a/java/ql/test/kotlin/library-tests/trap/diags.expected +++ b/java/ql/test/kotlin/library-tests/trap/diags.expected @@ -1,9 +1,11 @@ -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:22:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | -| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBC"' ...while extracting a expression () at long_string.kt:14:31:14:1048605\n ...while extracting a variable expr (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a variable (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a statement (longStringLiteral1) at long_string.kt:14:9:14:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | +| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCD"' ...while extracting a expression () at long_string.kt:15:31:15:1048606\n ...while extracting a variable expr (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a variable (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a statement (longStringLiteral2) at long_string.kt:15:9:15:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:24:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048579 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048579 | DATE TIME Truncated string of length 1048579\nTruncated string of length 1048579, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE"' ...while extracting a expression () at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:9:16:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 1048580 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048580 | DATE TIME Truncated string of length 1048580\nTruncated string of length 1048580, starting '"ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF"' ...while extracting a expression () at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:9:17:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | +| file://:0:0:0:0 | Truncated string of length 2097153 | CodeQL Kotlin extractor | 2 | | Truncated string of length 2097153 | DATE TIME Truncated string of length 2097153\nTruncated string of length 2097153, starting '"A\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"', ending '"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"\\"CDEF"' ...while extracting a expression () at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:9:18:26\n ...while extracting a block body () at long_string.kt:13:22:19:1\n ...while extracting a body () at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n | diff --git a/java/ql/test/kotlin/library-tests/trap/literals.ql b/java/ql/test/kotlin/library-tests/trap/literals.ql index 1490a21b458..b6dc1dcff6f 100644 --- a/java/ql/test/kotlin/library-tests/trap/literals.ql +++ b/java/ql/test/kotlin/library-tests/trap/literals.ql @@ -1,6 +1,6 @@ import java from Literal l, int len -where len = l.getValue().length() +where len = l.getValue().length() and l.getFile().isSourceFile() select l.getLocation(), len, l.getValue().prefix(5) + "..." + l.getValue().suffix(len - 5), l.getPrimaryQlClasses() diff --git a/java/ql/test/kotlin/library-tests/trap/long_comments.kt b/java/ql/test/kotlin/library-tests/trap/long_comments.kt index 3c5cb1d3764..55db7520f21 100644 --- a/java/ql/test/kotlin/library-tests/trap/long_comments.kt +++ b/java/ql/test/kotlin/library-tests/trap/long_comments.kt @@ -18,4 +18,6 @@ // Diagnostic Matches: %Truncated string of length 1048577% // Diagnostic Matches: %Truncated string of length 1048578% - +// Diagnostic Matches: %Truncated string of length 1048579% +// Diagnostic Matches: %Truncated string of length 1048580% +// Diagnostic Matches: %Truncated string of length 2097153% diff --git a/java/ql/test/kotlin/library-tests/vararg/args.expected b/java/ql/test/kotlin/library-tests/vararg/args.expected index 1e5a60a3545..6f5e0fbc035 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.expected +++ b/java/ql/test/kotlin/library-tests/vararg/args.expected @@ -53,33 +53,33 @@ implicitVarargsArguments | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 0 | test.kt:35:24:35:25 | 20 | | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 1 | test.kt:35:28:35:29 | 21 | | test.kt:35:5:35:34 | funWithOnlyVarArgs(...) | 2 | test.kt:35:32:35:33 | 22 | -| test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 0 | test.kt:36:28:36:30 | foo | +| test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 0 | test.kt:36:28:36:30 | "foo" | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 1 | test.kt:36:34:36:37 | true | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 2 | test.kt:36:40:36:41 | 30 | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 3 | test.kt:36:44:36:45 | 31 | | test.kt:36:5:36:50 | funWithArgsAndVarArgs(...) | 4 | test.kt:36:48:36:49 | 32 | -| test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 0 | test.kt:37:27:37:29 | foo | +| test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 0 | test.kt:37:27:37:29 | "foo" | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 1 | test.kt:37:33:37:34 | 41 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 2 | test.kt:37:37:37:38 | 42 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 3 | test.kt:37:41:37:42 | 43 | | test.kt:37:5:37:53 | funWithMiddleVarArgs(...) | 4 | test.kt:37:49:37:52 | true | | test.kt:38:5:38:30 | funWithOnlyVarArgs(...) | 0 | test.kt:38:25:38:29 | array | -| test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 0 | test.kt:39:28:39:30 | foo | +| test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 0 | test.kt:39:28:39:30 | "foo" | | test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 1 | test.kt:39:34:39:37 | true | | test.kt:39:5:39:46 | funWithArgsAndVarArgs(...) | 2 | test.kt:39:41:39:45 | array | -| test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 0 | test.kt:40:27:40:29 | foo | +| test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 0 | test.kt:40:27:40:29 | "foo" | | test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 1 | test.kt:40:34:40:38 | array | | test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | 2 | test.kt:40:45:40:48 | true | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 0 | test.kt:41:26:41:27 | 51 | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 1 | test.kt:41:30:41:31 | 52 | | test.kt:41:5:41:36 | new HasVarargConstructor(...) | 2 | test.kt:41:34:41:35 | 53 | -| test.kt:42:5:42:43 | new HasVarargConstructor(...) | 0 | test.kt:42:27:42:29 | foo | +| test.kt:42:5:42:43 | new HasVarargConstructor(...) | 0 | test.kt:42:27:42:29 | "foo" | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 1 | test.kt:42:33:42:34 | 61 | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 2 | test.kt:42:37:42:38 | 62 | | test.kt:42:5:42:43 | new HasVarargConstructor(...) | 3 | test.kt:42:41:42:42 | 63 | | test.kt:43:5:43:38 | new SuperclassHasVarargConstructor(...) | 0 | test.kt:43:36:43:37 | 91 | | test.kt:44:5:44:32 | new HasVarargConstructor(...) | 0 | test.kt:44:27:44:31 | array | -| test.kt:45:5:45:39 | new HasVarargConstructor(...) | 0 | test.kt:45:27:45:29 | foo | +| test.kt:45:5:45:39 | new HasVarargConstructor(...) | 0 | test.kt:45:27:45:29 | "foo" | | test.kt:45:5:45:39 | new HasVarargConstructor(...) | 1 | test.kt:45:34:45:38 | array | | test.kt:55:13:55:43 | new X(...) | 0 | test.kt:55:42:55:42 | 1 | | test.kt:55:13:55:43 | new X(...) | 1 | test.kt:55:15:55:35 | tmp0_s | diff --git a/java/ql/test/kotlin/library-tests/variables/variableAccesses.ql b/java/ql/test/kotlin/library-tests/variables/variableAccesses.ql index 0fa6d19d142..2d6622d032c 100644 --- a/java/ql/test/kotlin/library-tests/variables/variableAccesses.ql +++ b/java/ql/test/kotlin/library-tests/variables/variableAccesses.ql @@ -1,6 +1,6 @@ import java -query predicate varAcc(VarAccess va) { any() } +query predicate varAcc(VarAccess va) { va.getFile().isSourceFile() } query predicate extensionReceiverAcc(ExtensionReceiverAccess va) { any() } diff --git a/java/ql/test/kotlin/library-tests/variables/variables.expected b/java/ql/test/kotlin/library-tests/variables/variables.expected index c4aaa4a1620..9b7abda1536 100644 --- a/java/ql/test/kotlin/library-tests/variables/variables.expected +++ b/java/ql/test/kotlin/library-tests/variables/variables.expected @@ -1,7 +1,7 @@ isFinal -| variables.kt:6:9:6:26 | int local1 | final | -| variables.kt:8:9:8:26 | int local2 | non-final | -| variables.kt:10:9:10:26 | int local3 | final | +| variables.kt:6:13:6:18 | int local1 | final | +| variables.kt:8:13:8:18 | int local2 | non-final | +| variables.kt:10:13:10:18 | int local3 | final | compileTimeConstant | variables.kt:3:5:3:21 | prop | | variables.kt:3:5:3:21 | this.prop | @@ -11,9 +11,9 @@ compileTimeConstant #select | variables.kt:3:5:3:21 | prop | int | variables.kt:3:21:3:21 | 1 | | variables.kt:5:20:5:29 | param | int | file://:0:0:0:0 | | -| variables.kt:6:9:6:26 | int local1 | int | variables.kt:6:22:6:26 | ... + ... | -| variables.kt:8:9:8:26 | int local2 | int | variables.kt:8:22:8:26 | ... + ... | -| variables.kt:10:9:10:26 | int local3 | int | variables.kt:10:22:10:26 | param | +| variables.kt:6:13:6:18 | int local1 | int | variables.kt:6:22:6:26 | ... + ... | +| variables.kt:8:13:8:18 | int local2 | int | variables.kt:8:22:8:26 | ... + ... | +| variables.kt:10:13:10:18 | int local3 | int | variables.kt:10:22:10:26 | param | | variables.kt:15:1:15:21 | topLevel | int | variables.kt:15:21:15:21 | 1 | | variables.kt:21:11:21:18 | o | C1 | file://:0:0:0:0 | | | variables.kt:21:11:21:18 | o | C1 | variables.kt:21:11:21:18 | o | diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.expected b/java/ql/test/kotlin/query-tests/AutoBoxing/AutoBoxing.expected similarity index 100% rename from java/ql/test/library-tests/dataflow/external-models/negativesummaries.expected rename to java/ql/test/kotlin/query-tests/AutoBoxing/AutoBoxing.expected diff --git a/java/ql/test/kotlin/query-tests/AutoBoxing/AutoBoxing.qlref b/java/ql/test/kotlin/query-tests/AutoBoxing/AutoBoxing.qlref new file mode 100644 index 00000000000..f116f3bd8b4 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/AutoBoxing/AutoBoxing.qlref @@ -0,0 +1 @@ +Violations of Best Practice/legacy/AutoBoxing.ql diff --git a/java/ql/test/kotlin/query-tests/AutoBoxing/Test.kt b/java/ql/test/kotlin/query-tests/AutoBoxing/Test.kt new file mode 100644 index 00000000000..ca3aa52b2c9 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/AutoBoxing/Test.kt @@ -0,0 +1,5 @@ +fun foo(x: Int?) { + if (x != null) { + println(x) + } +} diff --git a/swift/ql/test/extractor-tests/generated/UnspecifiedElement/UnspecifiedElement_getIndex.expected b/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.expected similarity index 100% rename from swift/ql/test/extractor-tests/generated/UnspecifiedElement/UnspecifiedElement_getIndex.expected rename to java/ql/test/kotlin/query-tests/CloseReader/CloseReader.expected diff --git a/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.kt b/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.kt new file mode 100644 index 00000000000..27358a35587 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.kt @@ -0,0 +1,7 @@ +import java.io.* + +fun test0() { + BufferedReader(FileReader("C:\\test.txt")).use { bw -> + bw.readLine() + } +} diff --git a/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.qlref b/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.qlref new file mode 100644 index 00000000000..1c808bb9f46 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/CloseReader/CloseReader.qlref @@ -0,0 +1 @@ +Likely Bugs/Resource Leaks/CloseReader.ql diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/bridge_to_objc.swift b/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.expected similarity index 100% rename from swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/bridge_to_objc.swift rename to java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.expected diff --git a/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.kt b/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.kt new file mode 100644 index 00000000000..820e40f5666 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.kt @@ -0,0 +1,45 @@ +import java.io.* + +fun test0() { + val bw = BufferedWriter(FileWriter("C:\\test.txt")) + bw.write("test") +} + +fun test1() { + BufferedWriter(FileWriter("C:\\test.txt")).use { bw -> + bw.write("test") + } +} + +fun test2() { + val bw = FileOutputStream(File.createTempFile("","")).bufferedWriter() + bw.write("test") +} + +fun test3() { + FileOutputStream(File.createTempFile("","")).bufferedWriter().use { bw -> + bw.write("test") + } +} + +fun test4() { + val bw = OutputStreamWriter(FileOutputStream(File.createTempFile("",""))).buffered() + bw.write("test") +} + +fun test5() { + OutputStreamWriter(FileOutputStream(File.createTempFile("",""))).buffered().use { bw -> + bw.write("test") + } +} + +fun test6() { + val bw = OutputStreamWriter(FileOutputStream(File.createTempFile("",""))) + bw.write("test") +} + +fun test7() { + OutputStreamWriter(FileOutputStream(File.createTempFile("",""))).use { bw -> + bw.write("test") + } +} diff --git a/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.qlref b/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.qlref new file mode 100644 index 00000000000..88008367363 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/CloseWriter/CloseWriter.qlref @@ -0,0 +1 @@ +Likely Bugs/Resource Leaks/CloseWriter.ql diff --git a/swift/ql/test/extractor-tests/generated/expr/OverloadedDeclRefExpr/OverloadedDeclRefExpr_getType.expected b/java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.expected similarity index 100% rename from swift/ql/test/extractor-tests/generated/expr/OverloadedDeclRefExpr/OverloadedDeclRefExpr_getType.expected rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.expected diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.qlref b/java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.qlref similarity index 100% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/ConfusingMethodSignature.qlref rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/ConfusingOverloading.qlref diff --git a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt b/java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt similarity index 78% rename from java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt rename to java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt index b802d9f76a0..37dbe32f378 100644 --- a/java/ql/test/kotlin/query-tests/ConfusingMethodSignature/Test.kt +++ b/java/ql/test/kotlin/query-tests/ConfusingOverloading/Test.kt @@ -12,3 +12,9 @@ class A { fun fn(value: T, i: Int = 1) {} fun fn(value: String, i: Int = 1) {} } + +class Foo { + val str by lazy { + "someString" + } +} diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref new file mode 100644 index 00000000000..d726e7e0849 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadClass.qlref @@ -0,0 +1 @@ +DeadCode/DeadClass.ql diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref new file mode 100644 index 00000000000..76204a1df5a --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/DeadMethod.qlref @@ -0,0 +1 @@ +DeadCode/DeadMethod.ql diff --git a/java/ql/test/kotlin/query-tests/DeadCode/Test.kt b/java/ql/test/kotlin/query-tests/DeadCode/Test.kt new file mode 100644 index 00000000000..67c4a2ae4a7 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadCode/Test.kt @@ -0,0 +1,31 @@ +sealed interface DbAddexpr + +class Label { +} + +fun getFreshIdLabel(): Label { + return Label() +} + +fun foo(): Label { + val x = getFreshIdLabel() + return x +} + +fun main1() { + print(foo()) +} + +class Foo { + data class DC(val x: Int, val y: Int) + + fun foo() { + val dc = DC(3, 4) + print(dc.x) + print(dc.y) + } +} + +fun main2() { + Foo().foo() +} diff --git a/java/ql/test/kotlin/query-tests/EmptyBlock/EmptyBlock.expected b/java/ql/test/kotlin/query-tests/EmptyBlock/EmptyBlock.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/EmptyBlock/EmptyBlock.qlref b/java/ql/test/kotlin/query-tests/EmptyBlock/EmptyBlock.qlref new file mode 100644 index 00000000000..b0a56e88aa4 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/EmptyBlock/EmptyBlock.qlref @@ -0,0 +1 @@ +Likely Bugs/Statements/EmptyBlock.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/EmptyBlock/Test.kt b/java/ql/test/kotlin/query-tests/EmptyBlock/Test.kt new file mode 100644 index 00000000000..12624a92b38 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/EmptyBlock/Test.kt @@ -0,0 +1,13 @@ +class Foo { + abstract inner class Bar { + abstract fun myFun(): Int + } + + inner class Baz { + constructor() { + } + + fun fn() { + } + } +} diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt index 6eef90c517c..d5d230bffef 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt @@ -17,3 +17,9 @@ data class G(val x: Int) { return other != null && other.javaClass == this.javaClass } } + +data class H(val x: Int) { + override fun equals(other: Any?): Boolean { + return other != null + } +} diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref new file mode 100644 index 00000000000..ab1dbe353ef --- /dev/null +++ b/java/ql/test/kotlin/query-tests/MutualDependency/MutualDependency.qlref @@ -0,0 +1 @@ +Architecture/Dependencies/MutualDependency.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt b/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt new file mode 100644 index 00000000000..b0a9a45603f --- /dev/null +++ b/java/ql/test/kotlin/query-tests/MutualDependency/Test.kt @@ -0,0 +1,8 @@ +package foo.bar + +class Foo { + private fun someFun() { + fun say(s: String) { println(s) } + say("Str") + } +} diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected new file mode 100644 index 00000000000..ffcd13ccc56 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.expected @@ -0,0 +1 @@ +| Test.kt:12:1:12:13 | aaaa | Class and interface names should start in uppercase. | diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref new file mode 100644 index 00000000000..6f76aed32cb --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/NamingConventionsRefTypes.qlref @@ -0,0 +1 @@ +Advisory/Naming/NamingConventionsRefTypes.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt new file mode 100644 index 00000000000..f62497d59c6 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NamingConventionsRefTypes/Test.kt @@ -0,0 +1,12 @@ +class Foo { + fun myFun() { + val nestedStr by lazy { + "another string" + } + + fun nestedFun() { + } + } +} + +class aaaa {} \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref new file mode 100644 index 00000000000..401d63757af --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableField.qlref @@ -0,0 +1 @@ +Likely Bugs/Serialization/NonSerializableField.ql diff --git a/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt new file mode 100644 index 00000000000..bf790ea7c1e --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableField/NonSerializableFieldTest.kt @@ -0,0 +1,4 @@ +class Foo { + fun f(i: Int) {} + fun g(i: Int) { (this::f)(i) } +} diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref new file mode 100644 index 00000000000..4cbb0995764 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClass.qlref @@ -0,0 +1 @@ +Likely Bugs/Serialization/NonSerializableInnerClass.ql diff --git a/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt new file mode 100644 index 00000000000..3c3d72d0291 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/NonSerializableInnerClass/NonSerializableInnerClassTest.kt @@ -0,0 +1,11 @@ +import java.io.Serializable + +class A { + class X : Serializable { + } +} + +class B { + inner class X : Serializable { + } +} diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref new file mode 100644 index 00000000000..99f3f3f3293 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/OneStatementPerLine.qlref @@ -0,0 +1 @@ +Advisory/Statements/OneStatementPerLine.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt b/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt new file mode 100644 index 00000000000..0936ef67775 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/OneStatementPerLine/Test.kt @@ -0,0 +1,7 @@ +class Foo { + fun foo(): Foo { return this } + + fun bar(x: Foo?): Foo? { + return x?.foo() + } +} diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref new file mode 100644 index 00000000000..ef1dc964d95 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/ReturnValueIgnored.qlref @@ -0,0 +1 @@ +Likely Bugs/Statements/ReturnValueIgnored.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt new file mode 100644 index 00000000000..8520b3cedfc --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ReturnValueIgnored/Test.kt @@ -0,0 +1,16 @@ +class Foo { + fun foo(): Int { return 5 } + fun bar() { + val x0 = foo() + val x1 = foo() + val x2 = foo() + val x3 = foo() + val x4 = foo() + val x5 = foo() + val x6 = foo() + val x7 = foo() + val x8 = foo() + val x9 = foo() + val x = if (true) { foo() } else 6 + } +} diff --git a/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.expected b/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.kt b/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.kt new file mode 100644 index 00000000000..9facfd01785 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.kt @@ -0,0 +1,13 @@ +fun main() { + f(null) + f(true) + f(false) +} + +fun f(x: Boolean?) { + if(x == true) { + println("Yes") + } else { + println("No") + } +} diff --git a/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.qlref b/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.qlref new file mode 100644 index 00000000000..d071e989ebb --- /dev/null +++ b/java/ql/test/kotlin/query-tests/SimplifyBoolExpr/SimplifyBoolExpr.qlref @@ -0,0 +1 @@ +Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql diff --git a/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected b/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected index dc118062b3d..48fa4a1e4ab 100644 --- a/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected +++ b/java/ql/test/kotlin/query-tests/UnderscoreIdentifier/test.expected @@ -1,7 +1,7 @@ -| Test.kt:3:9:3:31 | List l | +| Test.kt:3:13:3:13 | List l | | Test.kt:4:28:4:32 | index | | Test.kt:4:35:4:35 | p1 | -| Test.kt:6:9:6:26 | Pair p | +| Test.kt:6:13:6:13 | Pair p | | Test.kt:7:14:7:18 | int first | | Test.kt:7:26:7:26 | Pair tmp0_container | | Test.kt:8:14:8:25 | Exception _ | diff --git a/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt b/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt index 4e41e048aa4..d5e6c5ef7b7 100644 --- a/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt +++ b/java/ql/test/kotlin/query-tests/UselessParameter/Test.kt @@ -19,3 +19,6 @@ object O {} fun C.fn() {} fun C.Companion.fn() {} fun O.fn() {} + +@Suppress("UNUSED_PARAMETER") +fun fn2(a: Int) {} diff --git a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected index 72b3348a019..e69de29bb2d 100644 --- a/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected +++ b/java/ql/test/kotlin/query-tests/UselessParameter/UselessParameter.expected @@ -1,2 +0,0 @@ -| Test.kt:11:8:11:18 | a | The parameter 'a' is never used. | -| Test.kt:19:5:19:5 | | The parameter '' is never used. | diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml new file mode 100644 index 00000000000..5f35c923ad0 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["my.callback.qltest", "A", False, "applyConsumer1", "(Object,Consumer1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer1Field1Field2", "(A,A,Consumer1)", "", "Argument[0].Field[my.callback.qltest.A.field1]", "Argument[2].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer1Field1Field2", "(A,A,Consumer1)", "", "Argument[1].Field[my.callback.qltest.A.field2]", "Argument[2].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer2", "(Object,Consumer2)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer3", "(Object,Consumer3)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConsumer3_ret_postup", "(Consumer3)", "", "Argument[0].Parameter[0]", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "forEach", "(Object[],Consumer3)", "", "Argument[0].ArrayElement", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyProducer1", "(Producer1)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[0].ReturnValue", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] + diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql index 4771031581f..cadd07c6f41 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql @@ -1,28 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.ExternalFlow import TestUtilities.InlineExpectationsTest -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "my.callback.qltest;A;false;applyConsumer1;(Object,Consumer1);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer1Field1Field2;(A,A,Consumer1);;Argument[0].Field[my.callback.qltest.A.field1];Argument[2].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer1Field1Field2;(A,A,Consumer1);;Argument[1].Field[my.callback.qltest.A.field2];Argument[2].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer2;(Object,Consumer2);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer3;(Object,Consumer3);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConsumer3_ret_postup;(Consumer3);;Argument[0].Parameter[0];ReturnValue;value;manual", - "my.callback.qltest;A;false;forEach;(Object[],Consumer3);;Argument[0].ArrayElement;Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyProducer1;(Producer1);;Argument[0].ReturnValue;ReturnValue;value;manual", - "my.callback.qltest;A;false;produceConsume;(Producer1,Consumer3);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;produceConsume;(Producer1,Consumer3);;Argument[1].Parameter[0];ReturnValue;value;manual", - "my.callback.qltest;A;false;applyConverter1;(Object,Converter1);;Argument[0];Argument[1].Parameter[0];value;manual", - "my.callback.qltest;A;false;applyConverter1;(Object,Converter1);;Argument[1].ReturnValue;ReturnValue;value;manual" - ] - } -} - class Conf extends DataFlow::Configuration { Conf() { this = "qltest:callback-dispatch" } diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml new file mode 100644 index 00000000000..ebe7e3b6ea5 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["", "B", False, "readElement", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] + - ["", "B", False, "readElement", "(Stream)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ql b/java/ql/test/library-tests/dataflow/collections/containerflow.ql index 12f7a3ffd22..df1f397f059 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.ql +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ql @@ -1,19 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.ExternalFlow import TestUtilities.InlineFlowTest -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - ";B;false;readElement;(Spliterator);;Argument[0].Element;ReturnValue;value;manual", - ";B;false;readElement;(Stream);;Argument[0].Element;ReturnValue;value;manual" - ] - } -} - class HasFlowTest extends InlineFlowTest { override DataFlow::Configuration getTaintFlowConfig() { none() } } diff --git a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql b/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql deleted file mode 100644 index 8425cf880b0..00000000000 --- a/java/ql/test/library-tests/dataflow/external-models/negativesummaries.ql +++ /dev/null @@ -1,8 +0,0 @@ -/** - * CSV Validation of negative summaries. - */ - -import java -import semmle.code.java.dataflow.ExternalFlow -import CsvValidation -import semmle.code.java.dataflow.internal.NegativeSummary diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml new file mode 100644 index 00000000000..55a76b79b21 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: sinkModel + data: + - ["my.qltest", "B", False, "sink1", "(Object)", "", "Argument[0]", "qltest", "manual"] + - ["my.qltest", "B", False, "sinkMethod", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "ReturnValue", "qltest-retval", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "Argument", "qltest-arg", "manual"] + - ["my.qltest", "B$Tag", False, "", "", "Annotated", "", "qltest-nospec", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ql b/java/ql/test/library-tests/dataflow/external-models/sinks.ql index b44a9eefd88..5da8f29ff4c 100644 --- a/java/ql/test/library-tests/dataflow/external-models/sinks.ql +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ql @@ -1,21 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation - -class SinkModelTest extends SinkModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; kind` - "my.qltest;B;false;sink1;(Object);;Argument[0];qltest;manual", - "my.qltest;B;false;sinkMethod;();;ReturnValue;qltest;manual", - "my.qltest;B$Tag;false;;;Annotated;ReturnValue;qltest-retval;manual", - "my.qltest;B$Tag;false;;;Annotated;Argument;qltest-arg;manual", - "my.qltest;B$Tag;false;;;Annotated;;qltest-nospec;manual" - ] - } -} +import ModelValidation from DataFlow::Node node, string kind where sinkNode(node, kind) diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml new file mode 100644 index 00000000000..7730d41e549 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml @@ -0,0 +1,21 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: sourceModel + data: + - ["my.qltest", "A", False, "src1", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src1", "(String)", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src1", "(java.lang.String)", "", "ReturnValue", "qltest-alt", "manual"] + - ["my.qltest", "A", False, "src1", "", "", "ReturnValue", "qltest-all-overloads", "manual"] + - ["my.qltest", "A", False, "src2", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", False, "src3", "()", "", "ReturnValue", "qltest", "manual"] + - ["my.qltest", "A", True, "src2", "()", "", "ReturnValue", "qltest-w-subtypes", "manual"] + - ["my.qltest", "A", True, "src3", "()", "", "ReturnValue", "qltest-w-subtypes", "manual"] + - ["my.qltest", "A", False, "srcArg", "(Object)", "", "Argument[0]", "qltest-argnum", "manual"] + - ["my.qltest", "A", False, "srcArg", "(Object)", "", "Argument", "qltest-argany", "manual"] + - ["my.qltest", "A$Handler", True, "handle", "(Object)", "", "Parameter[0]", "qltest-param-override", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "ReturnValue", "qltest-retval", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "Parameter", "qltest-param", "manual"] + - ["my.qltest", "A$Tag", False, "", "", "Annotated", "", "qltest-nospec", "manual"] + - ["my.qltest", "A", False, "srcTwoArg", "(String,String)", "", "ReturnValue", "qltest-shortsig", "manual"] + - ["my.qltest", "A", False, "srcTwoArg", "(java.lang.String,java.lang.String)", "", "ReturnValue", "qltest-longsig", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ql b/java/ql/test/library-tests/dataflow/external-models/srcs.ql index 5e428c412ea..655fee35611 100644 --- a/java/ql/test/library-tests/dataflow/external-models/srcs.ql +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ql @@ -1,32 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation - -class SourceModelTest extends SourceModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; output; kind` - "my.qltest;A;false;src1;();;ReturnValue;qltest;manual", - "my.qltest;A;false;src1;(String);;ReturnValue;qltest;manual", - "my.qltest;A;false;src1;(java.lang.String);;ReturnValue;qltest-alt;manual", - "my.qltest;A;false;src1;;;ReturnValue;qltest-all-overloads;manual", - "my.qltest;A;false;src2;();;ReturnValue;qltest;manual", - "my.qltest;A;false;src3;();;ReturnValue;qltest;manual", - "my.qltest;A;true;src2;();;ReturnValue;qltest-w-subtypes;manual", - "my.qltest;A;true;src3;();;ReturnValue;qltest-w-subtypes;manual", - "my.qltest;A;false;srcArg;(Object);;Argument[0];qltest-argnum;manual", - "my.qltest;A;false;srcArg;(Object);;Argument;qltest-argany;manual", - "my.qltest;A$Handler;true;handle;(Object);;Parameter[0];qltest-param-override;manual", - "my.qltest;A$Tag;false;;;Annotated;ReturnValue;qltest-retval;manual", - "my.qltest;A$Tag;false;;;Annotated;Parameter;qltest-param;manual", - "my.qltest;A$Tag;false;;;Annotated;;qltest-nospec;manual", - "my.qltest;A;false;srcTwoArg;(String,String);;ReturnValue;qltest-shortsig;manual", - "my.qltest;A;false;srcTwoArg;(java.lang.String,java.lang.String);;ReturnValue;qltest-longsig;manual" - ] - } -} +import ModelValidation from DataFlow::Node node, string kind where sourceNode(node, kind) diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml new file mode 100644 index 00000000000..d68e50ce558 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["my.qltest", "C", False, "stepArgRes", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgArg", "(Object,Object)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgQual", "(Object)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["my.qltest", "C", False, "stepQualRes", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["my.qltest", "C", False, "stepQualArg", "(Object)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["my.qltest", "C", False, "stepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "generated"] + - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ql b/java/ql/test/library-tests/dataflow/external-models/steps.ql index eec52c383cd..e57c4d54b17 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ql +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ql @@ -1,26 +1,9 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow -import CsvValidation +import ModelValidation import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //`namespace; type; subtypes; name; signature; ext; input; output; kind` - "my.qltest;C;false;stepArgRes;(Object);;Argument[0];ReturnValue;taint;manual", - "my.qltest;C;false;stepArgArg;(Object,Object);;Argument[0];Argument[1];taint;manual", - "my.qltest;C;false;stepArgQual;(Object);;Argument[0];Argument[-1];taint;manual", - "my.qltest;C;false;stepQualRes;();;Argument[-1];ReturnValue;taint;manual", - "my.qltest;C;false;stepQualArg;(Object);;Argument[-1];Argument[0];taint;manual", - "my.qltest;C;false;stepArgResGenerated;(Object);;Argument[0];ReturnValue;taint;generated", - "my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[0];ReturnValue;taint;generated", - "my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[1];ReturnValue;taint;manual", - ] - } -} - from DataFlow::Node node1, DataFlow::Node node2 where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, _) select node1, node2 diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml new file mode 100644 index 00000000000..3d3bbe9fd47 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["my.qltest.synth", "A", False, "storeInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "value", "manual"] + - ["my.qltest.synth", "A", False, "storeTaintInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "taint", "manual"] + - ["my.qltest.synth", "A", False, "storeValue", "(String)", "", "Argument[0]", "SyntheticGlobal[db1]", "value", "manual"] + - ["my.qltest.synth", "A", False, "readValue", "()", "", "SyntheticGlobal[db1]", "ReturnValue", "value", "manual"] + - ["my.qltest.synth", "A", False, "readArray", "()", "", "SyntheticGlobal[db1].ArrayElement", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ql b/java/ql/test/library-tests/dataflow/synth-global/test.ql index 47a1573865c..0d9f2265afc 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ql +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ql @@ -1,16 +1,3 @@ import java import TestUtilities.InlineFlowTest -import CsvValidation - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - "my.qltest.synth;A;false;storeInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;value;manual", - "my.qltest.synth;A;false;storeTaintInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;taint;manual", - "my.qltest.synth;A;false;storeValue;(String);;Argument[0];SyntheticGlobal[db1];value;manual", - "my.qltest.synth;A;false;readValue;();;SyntheticGlobal[db1];ReturnValue;value;manual", - "my.qltest.synth;A;false;readArray;();;SyntheticGlobal[db1].ArrayElement;ReturnValue;value;manual", - ] - } -} +import ModelValidation diff --git a/java/ql/test/library-tests/dataflow/taintsources/local.ql b/java/ql/test/library-tests/dataflow/taintsources/local.ql index 61faff7a992..62ad797be67 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/local.ql +++ b/java/ql/test/library-tests/dataflow/taintsources/local.ql @@ -2,11 +2,8 @@ import java import semmle.code.java.dataflow.FlowSources import TestUtilities.InlineExpectationsTest -class LocalSource extends DataFlow::Node { - LocalSource() { - this instanceof UserInput and - not this instanceof RemoteFlowSource - } +class LocalSource extends DataFlow::Node instanceof UserInput { + LocalSource() { not this instanceof RemoteFlowSource } } predicate isTestSink(DataFlow::Node n) { diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/AndroidManifest.xml b/java/ql/test/library-tests/frameworks/android/activity-alias/AndroidManifest.xml new file mode 100644 index 00000000000..586545a3b6c --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/AndroidManifest.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/Example2Activity.java b/java/ql/test/library-tests/frameworks/android/activity-alias/Example2Activity.java new file mode 100644 index 00000000000..551ed57918f --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/Example2Activity.java @@ -0,0 +1,7 @@ +package com.example.myapplication; + +import android.app.Activity; + +public class Example2Activity extends Activity { + +} diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/ExampleActivity.java b/java/ql/test/library-tests/frameworks/android/activity-alias/ExampleActivity.java new file mode 100644 index 00000000000..7f0469ff1d1 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/ExampleActivity.java @@ -0,0 +1,7 @@ +package com.example.myapplication; + +import android.app.Activity; + +public class ExampleActivity extends Activity { + +} diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.expected b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.expected new file mode 100644 index 00000000000..7d350358305 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.expected @@ -0,0 +1,5 @@ +| .AnotherAlias | .AnotherActivity | +| .Example2Alias | .Example2Activity | +| .ExampleAlias | .ExampleActivity | +| .MainAlias | .MainActivity | +| .SecondAlias | .MainActivity | diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.ql b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.ql new file mode 100644 index 00000000000..b7322a55027 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAlias.ql @@ -0,0 +1,5 @@ +import java +import semmle.code.xml.AndroidManifest + +from AndroidActivityAliasXmlElement alias +select alias.getComponentName(), alias.getTarget().getComponentName() diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.expected b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.expected new file mode 100644 index 00000000000..c5993ebf6e4 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.expected @@ -0,0 +1,4 @@ +| Example2Activity.java:5:14:5:29 | Example2Activity | AndroidManifest.xml:68:9:72:20 | activity | +| Example2Activity.java:5:14:5:29 | Example2Activity | AndroidManifest.xml:74:9:82:26 | activity-alias | +| ExampleActivity.java:5:14:5:28 | ExampleActivity | AndroidManifest.xml:55:9:59:25 | activity | +| ExampleActivity.java:5:14:5:28 | ExampleActivity | AndroidManifest.xml:61:9:66:26 | activity-alias | diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.ql b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.ql new file mode 100644 index 00000000000..beac467fc0a --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/TestActivityAliasExports.ql @@ -0,0 +1,6 @@ +import java +import semmle.code.java.frameworks.android.Android + +from ExportableAndroidComponent component +where component.isExported() +select component, component.getAndroidComponentXmlElement() diff --git a/java/ql/test/library-tests/frameworks/android/activity-alias/options b/java/ql/test/library-tests/frameworks/android/activity-alias/options new file mode 100644 index 00000000000..5aa323ada52 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/activity-alias/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0/ diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml new file mode 100644 index 00000000000..cf5c80bc456 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapKeyDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["generatedtest", "Test", False, "getMapValueDefault", "(Object)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "getMapKeyDefault", "(Object)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql index 2fa9dc00fd8..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql @@ -1,15 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newWithMapValueDefault;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newWithMapKeyDefault;(Object);;Argument[0];ReturnValue.MapKey;value;manual", - "generatedtest;Test;false;getMapValueDefault;(Object);;Argument[0].MapValue;ReturnValue;value;manual", - "generatedtest;Test;false;getMapKeyDefault;(Object);;Argument[0].MapKey;ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml new file mode 100644 index 00000000000..31321102a46 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "newBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newPersistableBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "getMapValue", "(BaseBundle)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "newWithIntent_extras", "(Bundle)", "", "Argument[0]", "ReturnValue.SyntheticField[android.content.Intent.extras]", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ql b/java/ql/test/library-tests/frameworks/android/intent/test.ql index a11619fb013..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.ql +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ql @@ -1,15 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newBundleWithMapValue;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newPersistableBundleWithMapValue;(Object);;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;getMapValue;(BaseBundle);;Argument[0].MapValue;ReturnValue;value;manual", - "generatedtest;Test;false;newWithIntent_extras;(Bundle);;Argument[0];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml new file mode 100644 index 00000000000..bd5c804fddc --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "getMapKeyDefault", "(Bundle)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ql b/java/ql/test/library-tests/frameworks/android/notification/test.ql index d0dffb02d6b..f0a60550d4d 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.ql +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ql @@ -1,13 +1,3 @@ import java import semmle.code.java.frameworks.android.Intent import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;getMapKeyDefault;(Bundle);;Argument[0].MapKey;ReturnValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml new file mode 100644 index 00000000000..a5d1cc8e1ab --- /dev/null +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "newRBWithMapValue", "", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] + - ["generatedtest", "Test", False, "newRBWithMapKey", "", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ql b/java/ql/test/library-tests/frameworks/apache-collections/test.ql index fae8e0bdd77..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.ql +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ql @@ -1,13 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newRBWithMapValue;;;Argument[0];ReturnValue.MapValue;value;manual", - "generatedtest;Test;false;newRBWithMapKey;;;Argument[0];ReturnValue.MapKey;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml new file mode 100644 index 00000000000..153b649a3e6 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "newWithElementDefault", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapKeyDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapKey", "value", "manual"] + - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql index dfafbea561f..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql @@ -1,14 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - [ - //"package;type;overrides;name;signature;ext;inputspec;outputspec;kind", - "generatedtest;Test;false;newWithElementDefault;(Object);;Argument[0];ReturnValue.Element;value;manual", - "generatedtest;Test;false;newWithMapKeyDefault;(Object);;Argument[0];ReturnValue.MapKey;value;manual", - "generatedtest;Test;false;newWithMapValueDefault;(Object);;Argument[0];ReturnValue.MapValue;value;manual" - ] - } -} diff --git a/java/ql/test/library-tests/frameworks/stream/test.ext.yml b/java/ql/test/library-tests/frameworks/stream/test.ext.yml new file mode 100644 index 00000000000..4f1cc3e38ac --- /dev/null +++ b/java/ql/test/library-tests/frameworks/stream/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "getElementSpliterator", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/stream/test.ql b/java/ql/test/library-tests/frameworks/stream/test.ql index adfc47bd521..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.ql +++ b/java/ql/test/library-tests/frameworks/stream/test.ql @@ -1,9 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = - "generatedtest;Test;false;getElementSpliterator;(Spliterator);;Argument[0].Element;ReturnValue;value;manual" - } -} diff --git a/java/ql/test/library-tests/optional/test.ext.yml b/java/ql/test/library-tests/optional/test.ext.yml new file mode 100644 index 00000000000..2aebf3bdb97 --- /dev/null +++ b/java/ql/test/library-tests/optional/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "getStreamElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/optional/test.ql b/java/ql/test/library-tests/optional/test.ql index b0d5ab16112..5d91e4e8e26 100644 --- a/java/ql/test/library-tests/optional/test.ql +++ b/java/ql/test/library-tests/optional/test.ql @@ -1,8 +1,2 @@ import java import TestUtilities.InlineFlowTest - -class SummaryModelTest extends SummaryModelCsv { - override predicate row(string row) { - row = "generatedtest;Test;false;getStreamElement;;;Argument[0].Element;ReturnValue;value;manual" - } -} diff --git a/java/ql/test/library-tests/paths/Test.java b/java/ql/test/library-tests/paths/Test.java index 3ba4d97ca78..b00a667d823 100644 --- a/java/ql/test/library-tests/paths/Test.java +++ b/java/ql/test/library-tests/paths/Test.java @@ -2,6 +2,7 @@ package generatedtest; import java.io.File; import java.net.URI; +import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.Paths; @@ -13,6 +14,119 @@ public class Test { public void test() throws Exception { + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + File in = (File)source(); + out = new File(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File(in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[0];Argument[-1];taint;manual" + File out = null; + URI in = (URI)source(); + out = new File(in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File((File)null, in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;false;File;;;Argument[1];Argument[-1];taint;manual" + File out = null; + String in = (String)source(); + out = new File((String)null, in); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getAbsoluteFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + File in = (File)source(); + out = in.getAbsoluteFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getAbsolutePath;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.getAbsolutePath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getCanonicalFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + File in = (File)source(); + out = in.getCanonicalFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;getCanonicalPath;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.getCanonicalPath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toPath;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; + File in = (File)source(); + out = in.toPath(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + File in = (File)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "java.io;File;true;toURI;;;Argument[-1];ReturnValue;taint;manual" + URI out = null; + File in = (File)source(); + out = in.toURI(); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;FileSystem;true;getPath;;;Argument[0];ReturnValue;taint;manual" + Path out = null; + String in = (String)source(); + FileSystem instance = null; + out = instance.getPath(in, (String[])null); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint;manual" + File out = null; + Path in = (Path)source(); + out = in.toFile(); + sink(out); // $ hasTaintFlow + } + { + // "java.nio.file;Path;true;getParent;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; + Path in = (Path)source(); + out = in.getParent(); + sink(out); // $ hasTaintFlow + } { // "java.nio.file;Path;true;normalize;;;Argument[-1];ReturnValue;taint;manual" Path out = null; @@ -51,10 +165,10 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "java.nio.file;Path;true;toFile;;;Argument[-1];ReturnValue;taint;manual" - File out = null; + // "java.nio.file;Path;true;toAbsolutePath;;;Argument[-1];ReturnValue;taint;manual" + Path out = null; Path in = (Path)source(); - out = in.toFile(); + out = in.toAbsolutePath(); sink(out); // $ hasTaintFlow } { @@ -72,26 +186,26 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" + // "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual" Path out = null; String in = (String)source(); out = Paths.get(in, (String[])null); sink(out); // $ hasTaintFlow } { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" - Path out = null; - String[] in = (String[])source(); - out = Paths.get((String)null, in); - sink(out); // $ hasTaintFlow - } - { - // "java.nio.file;Paths;true;get;;;Argument[0..1];ReturnValue;taint;manual" + // "java.nio.file;Paths;true;get;;;Argument[0];ReturnValue;taint;manual" Path out = null; URI in = (URI)source(); out = Paths.get(in); sink(out); // $ hasTaintFlow } + { + // "java.nio.file;Paths;true;get;;;Argument[1].ArrayElement;ReturnValue;taint;manual" + Path out = null; + String[] in = (String[])new String[]{(String)source()}; + out = Paths.get((String)null, in); + sink(out); // $ hasTaintFlow + } } diff --git a/java/ql/test/library-tests/pathsanitizer/Test.java b/java/ql/test/library-tests/pathsanitizer/Test.java index 27a15d867ce..61e0f498bd8 100644 --- a/java/ql/test/library-tests/pathsanitizer/Test.java +++ b/java/ql/test/library-tests/pathsanitizer/Test.java @@ -279,7 +279,7 @@ public class Test { } private void blockListGuardValidation(String path) throws Exception { - if (path.contains("..") || !path.startsWith("/data")) + if (path.contains("..") || path.startsWith("/data")) throw new Exception(); } diff --git a/java/ql/test/library-tests/pathsanitizer/TestKt.kt b/java/ql/test/library-tests/pathsanitizer/TestKt.kt new file mode 100644 index 00000000000..d0a11dac0ee --- /dev/null +++ b/java/ql/test/library-tests/pathsanitizer/TestKt.kt @@ -0,0 +1,499 @@ +import java.io.File +import java.net.URI +import java.nio.file.Path +import java.nio.file.Paths +import android.net.Uri + +class TestKt { + fun source(): Any? { + return null + } + + fun sink(o: Any?) {} + + @Throws(Exception::class) + private fun exactPathMatchGuardValidation(path: String?) { + if (!path.equals("/safe/path")) throw Exception() + } + + @Throws(Exception::class) + fun exactPathMatchGuard() { + run { + val source = source() as String? + if (source!!.equals("/safe/path")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as URI? + if (source!!.equals(URI("http://safe/uri"))) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as File? + if (source!!.equals(File("/safe/file"))) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as Uri? + if (source!!.equals(Uri.parse("http://safe/uri"))) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + exactPathMatchGuardValidation(source) + sink(source) // Safe + } + } + + @Throws(Exception::class) + private fun allowListGuardValidation(path: String?) { + if (path!!.contains("..") || !path.startsWith("/safe")) throw Exception() + } + + @Throws(Exception::class) + fun allowListGuard() { + // Prefix check by itself is not enough + run { + val source = source() as String? + if (source!!.startsWith("/safe")) { + sink(source) // $ hasTaintFlow + } else + sink(source) // $ hasTaintFlow + } + // PathTraversalGuard + allowListGuard + run { + val source = source() as String? + if (!source!!.contains("..") && source.startsWith("/safe")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.indexOf("..") == -1 && source.startsWith("/safe")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.lastIndexOf("..") == -1 && source.startsWith("/safe")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + // PathTraversalSanitizer + allowListGuard + run { + val source: File? = source() as File? + val normalized: String = source!!.canonicalPath + if (normalized.startsWith("/safe")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source: File? = source() as File? + val normalized: File = source!!.canonicalFile + if (normalized.startsWith("/safe")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source: File? = source() as File? + val normalized: String = source!!.canonicalFile.toString() + if (normalized.startsWith("/safe")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source = source() as String? + val normalized: Path = Paths.get(source).normalize() + if (normalized.startsWith("/safe")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.startsWith("/safe")) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.regionMatches(0, "/safe", 0, 5)) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.matches("/safe/.*".toRegex())) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + // validation method + run { + val source = source() as String? + allowListGuardValidation(source) + sink(source) // Safe + } + // PathInjectionSanitizer + partial string match is considered unsafe + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.contains("/safe")) { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.regionMatches(1, "/safe", 0, 5)) { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (normalized.matches(".*/safe/.*".toRegex())) { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + } + + @Throws(Exception::class) + private fun dotDotCheckGuardValidation(path: String?) { + if (!path!!.startsWith("/safe") || path.contains("..")) throw Exception() + } + + @Throws(Exception::class) + fun dotDotCheckGuard() { + // dot dot check by itself is not enough + run { + val source = source() as String? + if (!source!!.contains("..")) { + sink(source) // $ hasTaintFlow + } else + sink(source) // $ hasTaintFlow + } + // allowListGuard + dotDotCheckGuard + run { + val source = source() as String? + if (source!!.startsWith("/safe") && !source.contains("..")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.startsWith("/safe") && source.indexOf("..") == -1) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (!source!!.startsWith("/safe") || source.indexOf("..") != -1) + sink(source) // $ hasTaintFlow + else + sink(source) // Safe + } + run { + val source = source() as String? + if (source!!.startsWith("/safe") && source.lastIndexOf("..") == -1) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + // blockListGuard + dotDotCheckGuard + run { + val source = source() as String? + if (!source!!.startsWith("/data") && !source.contains("..")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (!source!!.startsWith("/data") && source.indexOf("..") == -1) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.startsWith("/data") || source.indexOf("..") != -1) + sink(source) // $ hasTaintFlow + else + sink(source) // Safe + } + run { + val source = source() as String? + if (!source!!.startsWith("/data") && source.lastIndexOf("..") == -1) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + // validation method + run { + val source = source() as String? + dotDotCheckGuardValidation(source) + sink(source) // Safe + } + } + + @Throws(Exception::class) + private fun blockListGuardValidation(path: String?) { + if (path!!.contains("..") || path.startsWith("/data")) throw Exception() + } + + @Throws(Exception::class) + fun blockListGuard() { + // Prefix check by itself is not enough + run { + val source = source() as String? + if (!source!!.startsWith("/data")) { + sink(source) // $ hasTaintFlow + } else + sink(source) // $ hasTaintFlow + } + // PathTraversalGuard + blockListGuard + run { + val source = source() as String? + if (!source!!.contains("..") && !source.startsWith("/data")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.indexOf("..") == -1 && !source.startsWith("/data")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + run { + val source = source() as String? + if (source!!.lastIndexOf("..") == -1 && !source.startsWith("/data")) + sink(source) // Safe + else + sink(source) // $ hasTaintFlow + } + // PathTraversalSanitizer + blockListGuard + run { + val source: File? = source() as File? + val normalized: String = source!!.canonicalPath + if (!normalized.startsWith("/data")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source: File? = source() as File? + val normalized: File = source!!.canonicalFile + if (!normalized.startsWith("/data")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source: File? = source() as File? + val normalized: String = source!!.canonicalFile.toString() + if (!normalized.startsWith("/data")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source = source() as String? + val normalized: Path = Paths.get(source).normalize() + if (!normalized.startsWith("/data")) { + sink(source) // Safe + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.startsWith("/data")) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.regionMatches(0, "/data", 0, 5)) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.matches("/data/.*".toRegex())) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + // validation method + run { + val source = source() as String? + blockListGuardValidation(source) + sink(source) // Safe + } + // PathInjectionSanitizer + partial string match with disallowed words + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.contains("/")) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.regionMatches(1, "/", 0, 5)) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.matches("/".toRegex())) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + // PathInjectionSanitizer + partial string match with disallowed prefixes + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.contains("/data")) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.regionMatches(1, "/data", 0, 5)) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + run { + val source = source() as String? + // normalize().toString() gets extracted as Object.toString, stopping taint here + val normalized: String = Paths.get(source).normalize().toString() + if (!normalized.matches(".*/data/.*".toRegex())) { + sink(source) // $ SPURIOUS: hasTaintFlow + sink(normalized) // Safe + } else { + sink(source) // $ hasTaintFlow + sink(normalized) // $ MISSING: hasTaintFlow + } + } + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/pathsanitizer/options b/java/ql/test/library-tests/pathsanitizer/options index 1e6e9ea2bf1..02ea18b0cac 100644 --- a/java/ql/test/library-tests/pathsanitizer/options +++ b/java/ql/test/library-tests/pathsanitizer/options @@ -1 +1,2 @@ //semmle-extractor-options: --javac-args -cp ${testdir}/../../stubs/google-android-9.0.0 +//codeql-extractor-kotlin-options: ${testdir}/../../stubs/google-android-9.0.0 diff --git a/java/ql/test/library-tests/regex/parser/RegexParseTests.ql b/java/ql/test/library-tests/regex/parser/RegexParseTests.ql index 345031a3b2d..4c8d7519f14 100644 --- a/java/ql/test/library-tests/regex/parser/RegexParseTests.ql +++ b/java/ql/test/library-tests/regex/parser/RegexParseTests.ql @@ -1,10 +1,12 @@ import java -import semmle.code.java.regex.RegexTreeView -import semmle.code.java.regex.regex +import semmle.code.java.regex.RegexTreeView as RegexTreeView +import semmle.code.java.regex.regex as Regex -string getQLClases(RegExpTerm t) { result = "[" + strictconcat(t.getPrimaryQLClass(), ",") + "]" } +string getQLClases(RegexTreeView::RegExpTerm t) { + result = "[" + strictconcat(t.getPrimaryQLClass(), ",") + "]" +} -query predicate parseFailures(Regex r, int i) { r.failedToParse(i) } +query predicate parseFailures(Regex::Regex r, int i) { r.failedToParse(i) } -from RegExpTerm t +from RegexTreeView::RegExpTerm t select t, getQLClases(t) diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.expected b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.expected new file mode 100644 index 00000000000..2ce20c00cb4 --- /dev/null +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.expected @@ -0,0 +1 @@ +| org.apache.commons.io | 14 | 1 | 1 | 2 | 18 | 0.8888888888888888 | 0.8333333333333334 | 0.1111111111111111 | 0.5 | 0.06666666666666667 | 0.16666666666666666 | diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.qlref b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.qlref new file mode 100644 index 00000000000..18e1cb980d9 --- /dev/null +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/GeneratedVsManualCoverage.qlref @@ -0,0 +1 @@ +Metrics/Summaries/GeneratedVsManualCoverage.ql diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/IOUtils.java b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/IOUtils.java new file mode 100644 index 00000000000..0bd11f545ac --- /dev/null +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/IOUtils.java @@ -0,0 +1,34 @@ +package org.apache.commons.io; +import java.io.*; +import java.util.*; + +public class IOUtils { + + // Generated-only summaries + public static BufferedInputStream buffer(InputStream inputStream) { return null; } + public static void copy(InputStream input, Writer output, String inputEncoding) throws IOException { } + public static long copyLarge(Reader input, Writer output) throws IOException { return 42; } + public static int read(InputStream input, byte[] buffer) throws IOException { return 42; } + public static void readFully(InputStream input, byte[] buffer) throws IOException { } + public static byte[] readFully(InputStream input, int length) throws IOException { return null; } + public static List readLines(InputStream input, String encoding) throws IOException { return null; } + public static BufferedReader toBufferedReader(Reader reader) { return null; } + public static byte[] toByteArray(InputStream input, int size) throws IOException { return null; } + public static char[] toCharArray(InputStream is, String encoding) throws IOException { return null; } + public static InputStream toInputStream(String input, String encoding) throws IOException { return null; } + public static String toString(InputStream input, String encoding) throws IOException { return null; } + public static void write(char[] data, Writer output) throws IOException { } + public static void writeChunked(char[] data, Writer output) throws IOException { } + + // Manual-only summary (generated neutral) + public static InputStream toBufferedInputStream(InputStream input) throws IOException { return null; } + + // Both + public static void writeLines(Collection lines, String lineEnding, Writer writer) throws IOException { } + + // No model + public static void noSummary(String string) throws IOException { } + + // Generated neutral + public static void copy(Reader input, OutputStream output) throws IOException { } +} diff --git a/java/ql/test/query-tests/Metrics/A.java b/java/ql/test/query-tests/Metrics/LinesOfCode/A.java similarity index 100% rename from java/ql/test/query-tests/Metrics/A.java rename to java/ql/test/query-tests/Metrics/LinesOfCode/A.java diff --git a/java/ql/test/query-tests/Metrics/LinesOfCode.expected b/java/ql/test/query-tests/Metrics/LinesOfCode/LinesOfCode.expected similarity index 100% rename from java/ql/test/query-tests/Metrics/LinesOfCode.expected rename to java/ql/test/query-tests/Metrics/LinesOfCode/LinesOfCode.expected diff --git a/java/ql/test/query-tests/Metrics/LinesOfCode.qlref b/java/ql/test/query-tests/Metrics/LinesOfCode/LinesOfCode.qlref similarity index 100% rename from java/ql/test/query-tests/Metrics/LinesOfCode.qlref rename to java/ql/test/query-tests/Metrics/LinesOfCode/LinesOfCode.qlref diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected new file mode 100644 index 00000000000..8a20a6c6c7b --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -0,0 +1,10 @@ +| java.io.File#File(String) | 2 | +| java.net.URL#URL(String) | 2 | +| java.io.FileWriter#FileWriter(File) | 1 | +| java.lang.StringBuilder#append(String) | 1 | +| java.lang.StringBuilder#toString() | 1 | +| java.net.URL#openConnection() | 1 | +| java.net.URL#openStream() | 1 | +| java.net.URLConnection#getInputStream() | 1 | +| java.util.Map#put(Object,Object) | 1 | +| org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java new file mode 100644 index 00000000000..7dd289acbaa --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -0,0 +1,29 @@ +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.io.InputStream; +import java.net.URL; +import java.io.File; +import java.io.FileWriter; +import org.apache.commons.io.FileUtils; + +class SupportedExternalApis { + public static void main(String[] args) throws Exception { + StringBuilder builder = new StringBuilder(); // uninteresting (parameterless constructor) + builder.append("foo"); // supported summary + builder.toString(); // supported summary + + Map map = new HashMap<>(); // uninteresting (parameterless constructor) + map.put("foo", new Object()); // supported summary + + Duration d = java.time.Duration.ofMillis(1000); // not supported + + URL github = new URL("https://www.github.com/"); // supported summary + InputStream stream = github.openConnection().getInputStream(); // supported source (getInputStream), supported sink (openConnection) + + new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File) + new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL) + + FileUtils.deleteDirectory(new File("foo")); // supported negative summary (deleteDirectory), supported summary (File) + } +} diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref new file mode 100644 index 00000000000..2e12499cf62 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.qlref @@ -0,0 +1 @@ +Telemetry/SupportedExternalApis.ql diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/SetJavascriptEnabled.java b/java/ql/test/query-tests/security/CWE-079/semmle/tests/SetJavascriptEnabled.java new file mode 100644 index 00000000000..d5593e38678 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/SetJavascriptEnabled.java @@ -0,0 +1,18 @@ +package com.example.test; + +import android.webkit.WebView; +import android.webkit.WebSettings; + +public class SetJavascriptEnabled { + public static void configureWebViewUnsafe(WebView view) { + WebSettings settings = view.getSettings(); + settings.setJavaScriptEnabled(true); // $javascriptEnabled + } + + public static void configureWebViewSafe(WebView view) { + WebSettings settings = view.getSettings(); + + // Safe: Javascript disabled + settings.setJavaScriptEnabled(false); + } +} diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.expected b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.expected new file mode 100644 index 00000000000..22cb40574f4 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.expected @@ -0,0 +1 @@ +| SetJavascriptEnabled.java:9:9:9:43 | setJavaScriptEnabled(...) | JavaScript execution enabled in WebView. | diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.qlref b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.qlref new file mode 100644 index 00000000000..e9e8006886d --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/WebViewSetEnabledJavaScript.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options index 22487fb2daf..62fc56e6792 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0 diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.expected new file mode 100644 index 00000000000..78cf64f9aa5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.expected @@ -0,0 +1,3 @@ +| WebViewFileAccess.java:8:9:8:41 | setAllowFileAccess(...) | WebView setting setAllowFileAccess may allow for unauthorized access of sensitive information. | +| WebViewFileAccess.java:10:9:10:53 | setAllowFileAccessFromFileURLs(...) | WebView setting setAllowFileAccessFromFileURLs may allow for unauthorized access of sensitive information. | +| WebViewFileAccess.java:12:9:12:58 | setAllowUniversalAccessFromFileURLs(...) | WebView setting setAllowUniversalAccessFromFileURLs may allow for unauthorized access of sensitive information. | \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.java b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.java new file mode 100644 index 00000000000..f42dbfaa84a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.java @@ -0,0 +1,24 @@ +import android.webkit.WebView; +import android.webkit.WebSettings; + +class WebViewFileAccess { + void configure(WebView view) { + WebSettings settings = view.getSettings(); + + settings.setAllowFileAccess(true); + + settings.setAllowFileAccessFromFileURLs(true); + + settings.setAllowUniversalAccessFromFileURLs(true); + } + + void configureSafe(WebView view) { + WebSettings settings = view.getSettings(); + + settings.setAllowFileAccess(false); + + settings.setAllowFileAccessFromFileURLs(false); + + settings.setAllowUniversalAccessFromFileURLs(false); + } +} diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.qlref b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.qlref new file mode 100644 index 00000000000..6c3224a4a61 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/WebViewFileAccess.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/options b/java/ql/test/query-tests/security/CWE-200/semmle/tests/options index 8b14bf08cd2..21cf6382c4e 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/apache-commons-lang3-3.7/ \ No newline at end of file +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/apache-commons-lang3-3.7/:${testdir}/../../../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-311/CWE-614/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-311/CWE-614/semmle/tests/Test.java index 3274310a6b2..c198f522e30 100644 --- a/java/ql/test/query-tests/security/CWE-311/CWE-614/semmle/tests/Test.java +++ b/java/ql/test/query-tests/security/CWE-311/CWE-614/semmle/tests/Test.java @@ -84,5 +84,15 @@ class Test { response.addCookie(cookie); } + { + // GOOD: set secure flag in call to `createSecureCookie` + response.addCookie(createSecureCookie()); + } + } + + private static Cookie createSecureCookie() { + Cookie cookie = new Cookie("secret", "fakesecret"); + cookie.setSecure(constTrue); + return cookie; } } diff --git a/java/ql/test/query-tests/security/CWE-524/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-524/AndroidManifest.xml new file mode 100644 index 00000000000..54b933452c8 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/R.java b/java/ql/test/query-tests/security/CWE-524/R.java new file mode 100644 index 00000000000..46eb99e1b7b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/R.java @@ -0,0 +1,8 @@ +package com.example.test; + +public final class R { + public static final class id { + public static final int test7_password = 1; + public static final int test8_password = 2; + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql new file mode 100644 index 00000000000..26ce8bc7fb7 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql @@ -0,0 +1,19 @@ +import java +import semmle.code.java.security.SensitiveKeyboardCacheQuery +import TestUtilities.InlineExpectationsTest + +class SensitiveKeyboardCacheTest extends InlineExpectationsTest { + SensitiveKeyboardCacheTest() { this = "SensitiveKeyboardCacheTest" } + + override string getARelevantTag() { result = "hasResult" } + + override predicate hasActualResult(Location loc, string element, string tag, string value) { + exists(AndroidEditableXmlElement el | + el = getASensitiveCachedInput() and + loc = el.getLocation() and + element = el.toString() and + tag = "hasResult" and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-524/Test.java b/java/ql/test/query-tests/security/CWE-524/Test.java new file mode 100644 index 00000000000..0ceff44adde --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/Test.java @@ -0,0 +1,16 @@ +package com.example.test; +import android.app.Activity; +import android.os.Bundle; +import android.widget.EditText; +import android.view.View; +import android.text.InputType; + +class Test extends Activity { + public void onCreate(Bundle b) { + EditText test7pw = findViewById(R.id.test7_password); + test7pw.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + + EditText test8pw = requireViewById(R.id.test8_password); + test8pw.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/options b/java/ql/test/query-tests/security/CWE-524/options new file mode 100644 index 00000000000..126d514284a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml b/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml new file mode 100644 index 00000000000..107c13dd306 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-524/res/layout/Test.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql index bd600a6d8af..c8c1566a7a4 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql @@ -1,4 +1,3 @@ -import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.regexp.PolynomialReDoSQuery @@ -9,7 +8,10 @@ class HasPolyRedos extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasPolyRedos" and - exists(DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp | + exists( + DataFlow::PathNode source, DataFlow::PathNode sink, + SuperlinearBackTracking::PolynomialBackTrackingTerm regexp + | hasPolynomialReDoSResult(source, sink, regexp) and location = sink.getNode().getLocation() and element = sink.getNode().toString() and diff --git a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql index 288ca57f2e2..7226541bcb2 100644 --- a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql @@ -1,6 +1,7 @@ import java import TestUtilities.InlineExpectationsTest -import semmle.code.java.security.regexp.ExponentialBackTracking +private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView +import codeql.regex.nfa.ExponentialBackTracking::Make as ExponentialBackTracking import semmle.code.java.regex.regex class HasExpRedos extends InlineExpectationsTest { @@ -10,8 +11,8 @@ class HasExpRedos extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasExpRedos" and - exists(RegExpTerm t, string pump, State s, string prefixMsg | - hasReDoSResult(t, pump, s, prefixMsg) and + exists(TreeView::RegExpTerm t, string pump, ExponentialBackTracking::State s, string prefixMsg | + ExponentialBackTracking::hasReDoSResult(t, pump, s, prefixMsg) and not t.getRegex().getAMode() = "VERBOSE" and value = "" and location = t.getLocation() and diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.java b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.java similarity index 65% rename from java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.java rename to java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.java index 2aace93aeb8..5c7a3ca0574 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.java +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.java @@ -7,128 +7,119 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import org.apache.commons.lang3.RegExUtils; +import com.google.common.base.Splitter; -public class RegexInjection extends HttpServlet { +public class RegexInjectionTest extends HttpServlet { public boolean string1(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return input.matches("^" + pattern + "=.*$"); // BAD + return input.matches("^" + pattern + "=.*$"); // $ hasRegexInjection } public boolean string2(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return input.split(pattern).length > 0; // BAD + return input.split(pattern).length > 0; // $ hasRegexInjection } public boolean string3(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return input.replaceFirst(pattern, "").length() > 0; // BAD + return input.split(pattern, 0).length > 0; // $ hasRegexInjection } public boolean string4(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return input.replaceAll(pattern, "").length() > 0; // BAD + return input.replaceFirst(pattern, "").length() > 0; // $ hasRegexInjection + } + + public boolean string5(javax.servlet.http.HttpServletRequest request) { + String pattern = request.getParameter("pattern"); + String input = request.getParameter("input"); + + return input.replaceAll(pattern, "").length() > 0; // $ hasRegexInjection } public boolean pattern1(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - Pattern pt = Pattern.compile(pattern); + Pattern pt = Pattern.compile(pattern); // $ hasRegexInjection Matcher matcher = pt.matcher(input); - return matcher.find(); // BAD + return matcher.find(); } public boolean pattern2(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return Pattern.compile(pattern).matcher(input).matches(); // BAD + return Pattern.compile(pattern).matcher(input).matches(); // $ hasRegexInjection } public boolean pattern3(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return Pattern.matches(pattern, input); // BAD + return Pattern.compile(pattern, 0).matcher(input).matches(); // $ hasRegexInjection } public boolean pattern4(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return input.matches("^" + foo(pattern) + "=.*$"); // BAD - } - - String foo(String str) { - return str; + return Pattern.matches(pattern, input); // $ hasRegexInjection } public boolean pattern5(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - // GOOD: User input is sanitized before constructing the regex - return input.matches("^" + escapeSpecialRegexChars(pattern) + "=.*$"); + return input.matches("^" + foo(pattern) + "=.*$"); // $ hasRegexInjection } - public boolean pattern6(javax.servlet.http.HttpServletRequest request) { - String pattern = request.getParameter("pattern"); - String input = request.getParameter("input"); - - escapeSpecialRegexChars(pattern); - - // BAD: the pattern is not really sanitized - return input.matches("^" + pattern + "=.*$"); - } - - Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\]><-=!.+*?^$\\\\|]"); - - String escapeSpecialRegexChars(String str) { - return SPECIAL_REGEX_CHARS.matcher(str).replaceAll("\\\\$0"); + String foo(String str) { + return str; } public boolean apache1(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.removeAll(input, pattern).length() > 0; // BAD + return RegExUtils.removeAll(input, pattern).length() > 0; // $ hasRegexInjection } public boolean apache2(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.removeFirst(input, pattern).length() > 0; // BAD + return RegExUtils.removeFirst(input, pattern).length() > 0; // $ hasRegexInjection } public boolean apache3(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.removePattern(input, pattern).length() > 0; // BAD + return RegExUtils.removePattern(input, pattern).length() > 0; // $ hasRegexInjection } public boolean apache4(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.replaceAll(input, pattern, "").length() > 0; // BAD + return RegExUtils.replaceAll(input, pattern, "").length() > 0; // $ hasRegexInjection } public boolean apache5(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.replaceFirst(input, pattern, "").length() > 0; // BAD + return RegExUtils.replaceFirst(input, pattern, "").length() > 0; // $ hasRegexInjection } public boolean apache6(javax.servlet.http.HttpServletRequest request) { @@ -136,13 +127,40 @@ public class RegexInjection extends HttpServlet { String input = request.getParameter("input"); Pattern pt = (Pattern)(Object) pattern; - return RegExUtils.replaceFirst(input, pt, "").length() > 0; // GOOD, Pattern compile is the sink instead + return RegExUtils.replaceFirst(input, pt, "").length() > 0; // Safe: Pattern compile is the sink instead } public boolean apache7(javax.servlet.http.HttpServletRequest request) { String pattern = request.getParameter("pattern"); String input = request.getParameter("input"); - return RegExUtils.replacePattern(input, pattern, "").length() > 0; // BAD + return RegExUtils.replacePattern(input, pattern, "").length() > 0; // $ hasRegexInjection + } + + // test `Pattern.quote` sanitizer + public boolean quoteTest(javax.servlet.http.HttpServletRequest request) { + String pattern = request.getParameter("pattern"); + String input = request.getParameter("input"); + + return input.matches(Pattern.quote(pattern)); // Safe + } + + // test `Pattern.LITERAL` sanitizer + public boolean literalTest(javax.servlet.http.HttpServletRequest request) { + String pattern = request.getParameter("pattern"); + String input = request.getParameter("input"); + + return Pattern.compile(pattern, Pattern.LITERAL).matcher(input).matches(); // Safe + } + + public Splitter guava1(javax.servlet.http.HttpServletRequest request) { + String pattern = request.getParameter("pattern"); + return Splitter.onPattern(pattern); // $ hasRegexInjection + } + + public Splitter guava2(javax.servlet.http.HttpServletRequest request) { + String pattern = request.getParameter("pattern"); + // sink is `Pattern.compile` + return Splitter.on(Pattern.compile(pattern)); // $ hasRegexInjection } } diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql new file mode 100644 index 00000000000..368b5170bfc --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql @@ -0,0 +1,20 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.regexp.RegexInjectionQuery + +class RegexInjectionTest extends InlineExpectationsTest { + RegexInjectionTest() { this = "RegexInjectionTest" } + + override string getARelevantTag() { result = "hasRegexInjection" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasRegexInjection" and + exists(DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c | + c.hasFlowPath(source, sink) + | + location = sink.getNode().getLocation() and + element = sink.getNode().toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-730/options b/java/ql/test/query-tests/security/CWE-730/options index 2f7d22dc61c..884cb21114c 100644 --- a/java/ql/test/query-tests/security/CWE-730/options +++ b/java/ql/test/query-tests/security/CWE-730/options @@ -1 +1 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/guava-30.0 \ No newline at end of file +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/guava-30.0:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/apache-commons-lang3-3.7 diff --git a/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml b/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml index 2f96052d584..2dc5709b320 100644 --- a/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml +++ b/java/ql/test/query-tests/security/CWE-829/semmle/tests/secure-pom.xml @@ -61,5 +61,17 @@ https://insecure-repository.example + + disabled-repo + Disabled Repository + + false + + + false + + + http://insecure-repository.example + diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java index 9c8f098d467..746c9ca83dc 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java @@ -156,7 +156,7 @@ public class ImplicitPendingIntentsTest { PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, flag); // Sanitizer Intent fwdIntent = new Intent(); fwdIntent.putExtra("fwdIntent", pi); - ctx.startActivity(fwdIntent); // $ SPURIOUS: $ hasImplicitPendingIntent + ctx.startActivity(fwdIntent); // Safe } } diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java index cad1d58cad5..f292c6b1168 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java @@ -488,4 +488,8 @@ public class Activity extends ContextWrapper { public T findViewById(int id) { return null; } + + public T requireViewById(int id) { + return null; + } } diff --git a/java/ql/test/utils/flowtestcasegenerator/options b/java/ql/test/utils/flowtestcasegenerator/options new file mode 100644 index 00000000000..5ae5aad3008 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../stubs/apache-commons-collections4-4.4:${testdir}/../../stubs/apache-log4j-2.14.1:${testdir}/../../stubs/slf4j-2.0.0 \ No newline at end of file diff --git a/java/ql/test/utils/flowtestcasegenerator/pom.xml b/java/ql/test/utils/flowtestcasegenerator/pom.xml new file mode 100644 index 00000000000..b4fe0c30974 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/pom.xml @@ -0,0 +1,133 @@ + + 4.0.0 + + com.semmle + parent + 1.0 + + + google + Google Maven + https://maven.google.com/ + + + + 31 + 1.8 + 1.8 + + + + org.apache.logging.log4j + log4j-api + 2.14.1 + + + org.apache.logging.log4j + log4j-core + 2.14.1 + + + org.slf4j + slf4j-api + 2.0.0-alpha5 + + + org.jboss.logging + jboss-logging + 3.4.2.Final + + + org.springframework.ldap + spring-ldap + 1.3.1.RELEASE + pom + + + org.springframework.ldap + spring-ldap-core + 2.3.5.RELEASE + + + org.springframework + spring-web + 5.3.18 + + + org.springframework + spring-context + 5.3.18 + + + org.springframework + spring-webmvc + 5.3.18 + + + org.springframework.data + spring-data-commons + 2.6.3 + + + org.apache.shiro + shiro-core + 1.8.0 + + + org.apache.directory.api + api-ldap-client-all + 2.1.0 + + + org.owasp.esapi + esapi + 2.2.3.1 + + + com.unboundid + unboundid-ldapsdk + 6.0.3 + + + javax.servlet + javax.servlet-api + 4.0.1 + + + com.squareup.retrofit2 + retrofit + 2.9.0 + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + org.freemarker + freemarker + 2.3.31 + + + org.thymeleaf + thymeleaf + 3.0.15.RELEASE + + + com.hubspot.jinjava + jinjava + 2.6.0 + + + io.pebbletemplates + pebble + 3.1.5 + + + org.apache.velocity + velocity-engine-core + 2.3 + + + diff --git a/java/ql/test/utils/flowtestcasegenerator/specs.csv b/java/ql/test/utils/flowtestcasegenerator/specs.csv new file mode 100644 index 00000000000..93f59d05916 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/specs.csv @@ -0,0 +1,11 @@ +org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual +org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual +org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual +org.apache.commons.collections4;MapUtils;true;predicatedMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual +org.apache.commons.collections4;MapUtils;true;toMap;;;Argument[0].MapKey;ReturnValue.MapKey;value;manual +org.apache.commons.collections4;MapUtils;true;toMap;;;Argument[0].MapValue;ReturnValue.MapValue;value;manual \ No newline at end of file diff --git a/java/ql/test/utils/flowtestcasegenerator/test.py b/java/ql/test/utils/flowtestcasegenerator/test.py new file mode 100644 index 00000000000..47b7c3a61f2 --- /dev/null +++ b/java/ql/test/utils/flowtestcasegenerator/test.py @@ -0,0 +1,17 @@ +# This script is for debugging purposes for the flow test case generator. +# Some dummy tests are created and executed. +# It requites that `--search-path /path/to/semmle-code/ql` is added to `~/.config/codeql/config` + +# Usage: python3 test.py + +import subprocess + +# Generate test cases +print('Generating test cases...') +if subprocess.check_call(["../../../src/utils/flowtestcasegenerator/GenerateFlowTestCase.py", "specs.csv", "pom.xml", "--force", "."]): + print("Failed to generate test cases.") + exit(1) + +# Run test cases. +print('Running test cases...') +subprocess.call(["codeql", "test", "run", "test.ql"]) \ No newline at end of file diff --git a/java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref b/java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref deleted file mode 100644 index c24d124c0b2..00000000000 --- a/java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/model-generator/CaptureNegativeSummaryModels.ql \ No newline at end of file diff --git a/java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.expected b/java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.expected similarity index 61% rename from java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.expected rename to java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.expected index 36ac5cfe569..0c452b8c49d 100644 --- a/java/ql/test/utils/model-generator/dataflow/CaptureNegativeSummaryModels.expected +++ b/java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.expected @@ -1,25 +1,11 @@ -| p;AbstractImplOfExternalSPI;AbstractImplOfExternalSPI;();generated | | p;Factory;getIntValue;();generated | -| p;FinalClass;FinalClass;();generated | | p;FinalClass;returnsConstant;();generated | -| p;FluentAPI$Inner;Inner;();generated | | p;FluentAPI$Inner;notThis;(String);generated | -| p;FluentAPI;FluentAPI;();generated | | p;ImmutablePojo;getX;();generated | -| p;ImplOfExternalSPI;ImplOfExternalSPI;();generated | -| p;InnerClasses$CaptureMe;CaptureMe;();generated | -| p;InnerClasses;InnerClasses;();generated | -| p;InnerHolder;InnerHolder;();generated | | p;Joiner;length;();generated | -| p;MultipleImpls$Strat1;Strat1;();generated | -| p;MultipleImpls$Strat2;Strat2;();generated | -| p;MultipleImpls$Strat3;Strat3;();generated | | p;MultipleImpls$Strategy;doSomething;(String);generated | -| p;MultipleImpls;MultipleImpls;();generated | -| p;ParamFlow;ParamFlow;();generated | | p;ParamFlow;ignorePrimitiveReturnValue;(String);generated | | p;ParamFlow;mapType;(Class);generated | -| p;Pojo;Pojo;();generated | | p;Pojo;doNotSetValue;(String);generated | | p;Pojo;getBigDecimal;();generated | | p;Pojo;getBigInt;();generated | @@ -31,13 +17,10 @@ | p;Pojo;getPrimitiveArray;();generated | | p;PrivateFlowViaPublicInterface$SPI;openStream;();generated | | p;PrivateFlowViaPublicInterface$SPI;openStreamNone;();generated | -| p;PrivateFlowViaPublicInterface;PrivateFlowViaPublicInterface;();generated | | p;PrivateFlowViaPublicInterface;createAnSPIWithoutTrackingFile;(File);generated | -| p;Sinks;Sinks;();generated | | p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);generated | | p;Sinks;propagate;(String);generated | | p;Sinks;readUrl;(URL,Charset);generated | -| p;Sources;Sources;();generated | | p;Sources;readUrl;(URL);generated | | p;Sources;socketStream;();generated | | p;Sources;sourceToParameter;(InputStream[],List);generated | diff --git a/java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref b/java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref new file mode 100644 index 00000000000..cb6ef7faa65 --- /dev/null +++ b/java/ql/test/utils/model-generator/dataflow/CaptureNeutralModels.qlref @@ -0,0 +1 @@ +utils/model-generator/CaptureNeutralModels.ql \ No newline at end of file diff --git a/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme new file mode 100644 index 00000000000..4d00210ca57 --- /dev/null +++ b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme @@ -0,0 +1,1218 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +| 121 = @satisfies_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..c0664d5721c --- /dev/null +++ b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme @@ -0,0 +1,1217 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties new file mode 100644 index 00000000000..476d9aba57e --- /dev/null +++ b/javascript/downgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties @@ -0,0 +1,2 @@ +description: add support for TypeScript 4.9 +compatibility: backwards diff --git a/javascript/extractor/README.md b/javascript/extractor/README.md index e9495dd21ec..cf26d9db784 100644 --- a/javascript/extractor/README.md +++ b/javascript/extractor/README.md @@ -2,8 +2,8 @@ This directory contains the source code of the JavaScript extractor. The extractor depends on various libraries that are not currently bundled with the source code, so at present it cannot be built in isolation. -The extractor consists of a parser for the latest version of ECMAScript, including a few proposed and historic extensions (see `src/com/semmle/jcorn`), classes for representing JavaScript and TypeScript ASTs (`src/com/semmle/js/ast` and `src/com/semmle/ts/ast`), and various other bits of functionality. Historically, the main entry point of the JavaScript extractor has been `com.semmle.js.extractor.Main`. However, this class is slowly being phased out in favour of `com.semmle.js.extractor.AutoBuild`, which is the entry point used by LGTM. +The extractor consists of a parser for the latest version of ECMAScript, including a few proposed and historic extensions (see `src/com/semmle/jcorn`), classes for representing JavaScript and TypeScript ASTs (`src/com/semmle/js/ast` and `src/com/semmle/ts/ast`), and various other bits of functionality. Historically, the main entry point of the JavaScript extractor has been `com.semmle.js.extractor.Main`. However, this class is slowly being phased out in favour of `com.semmle.js.extractor.AutoBuild`, which is the entry point used by CodeQL. ## License -Like the LGTM queries, the JavaScript extractor is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com). Some code is derived from other projects, whose licenses are noted in other `LICENSE-*.md` files in this folder. +Like the CodeQL queries, the JavaScript extractor is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com). Some code is derived from other projects, whose licenses are noted in other `LICENSE-*.md` files in this folder. diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 2fbc09e8d9e..87c37660479 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "4.8.2" + "typescript": "4.9.3" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/src/ast_extractor.ts b/javascript/extractor/lib/typescript/src/ast_extractor.ts index b935294feb6..e462797867b 100644 --- a/javascript/extractor/lib/typescript/src/ast_extractor.ts +++ b/javascript/extractor/lib/typescript/src/ast_extractor.ts @@ -317,6 +317,7 @@ function isTypedNode(node: ts.Node): boolean { case ts.SyntaxKind.ArrayLiteralExpression: case ts.SyntaxKind.ArrowFunction: case ts.SyntaxKind.AsExpression: + case ts.SyntaxKind.SatisfiesExpression: case ts.SyntaxKind.AwaitExpression: case ts.SyntaxKind.BinaryExpression: case ts.SyntaxKind.CallExpression: diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 05fb731c9e4..03b6581fadb 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -6,7 +6,7 @@ version "12.7.11" resolved node-12.7.11.tgz#be879b52031cfb5d295b047f5462d8ef1a716446 -typescript@4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790" - integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw== +typescript@4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== diff --git a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java index c450fdd0468..cf57a3ead18 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java @@ -47,6 +47,7 @@ import com.semmle.ts.ast.TemplateLiteralTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.ts.ast.TypeExpression; import com.semmle.ts.ast.TypeParameter; import com.semmle.ts.ast.TypeofTypeExpr; @@ -683,6 +684,11 @@ public class DefaultVisitor implements Visitor { return visit((Expression) nd, c); } + @Override + public R visit(SatisfiesExpr nd, C c) { + return visit((Expression) nd, c); + } + @Override public R visit(MappedTypeExpr nd, C c) { return visit((TypeExpression) nd, c); diff --git a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java index 83a37e11534..aeea1b79cbc 100644 --- a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java +++ b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java @@ -46,6 +46,7 @@ import com.semmle.ts.ast.TemplateLiteralTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.ts.ast.TypeParameter; import com.semmle.ts.ast.TypeofTypeExpr; import com.semmle.ts.ast.UnaryTypeExpr; @@ -782,6 +783,14 @@ public class NodeCopier implements Visitor { nd.isAsExpression()); } + @Override + public INode visit(SatisfiesExpr nd, Void c) { + return new SatisfiesExpr( + visit(nd.getLoc()), + copy(nd.getExpression()), + copy(nd.getTypeAnnotation())); + } + @Override public INode visit(MappedTypeExpr nd, Void c) { return new MappedTypeExpr( diff --git a/javascript/extractor/src/com/semmle/js/ast/Visitor.java b/javascript/extractor/src/com/semmle/js/ast/Visitor.java index 3d595b981b8..e748e9b5a36 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Visitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/Visitor.java @@ -43,6 +43,7 @@ import com.semmle.ts.ast.TemplateLiteralTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.ts.ast.TypeParameter; import com.semmle.ts.ast.TypeofTypeExpr; import com.semmle.ts.ast.UnaryTypeExpr; @@ -276,6 +277,8 @@ public interface Visitor { public R visit(TypeAssertion nd, C c); + public R visit(SatisfiesExpr nd, C c); + public R visit(MappedTypeExpr nd, C c); public R visit(TypeAliasDeclaration nd, C c); diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 1f322935b56..0a85e1e87f0 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -154,6 +154,7 @@ import com.semmle.ts.ast.TemplateLiteralTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.ts.ast.TypeExpression; import com.semmle.ts.ast.TypeParameter; import com.semmle.ts.ast.TypeofTypeExpr; @@ -2111,6 +2112,14 @@ public class ASTExtractor { return key; } + @Override + public Label visit(SatisfiesExpr nd, Context c) { + Label key = super.visit(nd, c); + visit(nd.getExpression(), key, 0); + visit(nd.getTypeAnnotation(), key, 1, IdContext.TYPE_BIND); + return key; + } + @Override public Label visit(MappedTypeExpr nd, Context c) { Label key = super.visit(nd, c); diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index 101b8094fdd..bf5b4e8cb03 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -52,6 +52,7 @@ import com.semmle.util.exception.ResourceError; import com.semmle.util.exception.UserError; import com.semmle.util.extraction.ExtractorOutputConfig; import com.semmle.util.files.FileUtil; +import com.semmle.util.files.FileUtil8; import com.semmle.util.io.WholeIO; import com.semmle.util.io.csv.CSVReader; import com.semmle.util.language.LegacyLanguage; @@ -141,7 +142,7 @@ import com.semmle.util.trap.TrapWriter; *
  • All JavaScript files, that is, files with one of the extensions supported by {@link * FileType#JS} (currently ".js", ".jsx", ".mjs", ".cjs", ".es6", ".es"). *
  • All HTML files, that is, files with with one of the extensions supported by {@link - * FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue"). + * FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue", ".html.erb"). *
  • All YAML files, that is, files with one of the extensions supported by {@link * FileType#YAML} (currently ".raml", ".yaml", ".yml"). *
  • Files with base name "package.json" or "tsconfig.json", and files whose base name @@ -433,23 +434,41 @@ public class AutoBuild { return true; } + /** + * Returns whether the autobuilder has seen code. + * This is overridden in tests. + */ + protected boolean hasSeenCode() { + return seenCode; + } + /** Perform extraction. */ public int run() throws IOException { startThreadPool(); try { - extractSource(); - extractExterns(); + CompletableFuture sourceFuture = extractSource(); + sourceFuture.join(); // wait for source extraction to complete + if (hasSeenCode()) { // don't bother with the externs if no code was seen + extractExterns(); + } extractXml(); } finally { shutdownThreadPool(); } - if (!seenCode) { + if (!hasSeenCode()) { if (seenFiles) { warn("Only found JavaScript or TypeScript files that were empty or contained syntax errors."); } else { warn("No JavaScript or TypeScript code found."); } - return -1; + // ensuring that the finalize steps detects that no code was seen. + Path srcFolder = Paths.get(EnvironmentVariables.getWipDatabase(), "src"); + // check that the srcFolder is empty + if (Files.list(srcFolder).count() == 0) { + // Non-recursive delete because "src/" should be empty. + FileUtil8.delete(srcFolder); + } + return 0; } return 0; } @@ -571,7 +590,7 @@ public class AutoBuild { } /** Extract all supported candidate files that pass the filters. */ - private void extractSource() throws IOException { + private CompletableFuture extractSource() throws IOException { // default extractor FileExtractor defaultExtractor = new FileExtractor(mkExtractorConfig(), outputConfig, trapCache); @@ -618,7 +637,7 @@ public class AutoBuild { boolean hasTypeScriptFiles = extractedFiles.size() > 0; // extract remaining files - extractFiles( + return extractFiles( filesToExtract, extractedFiles, extractors, f -> !(hasTypeScriptFiles && isFileDerivedFromTypeScriptFile(f, extractedFiles))); } diff --git a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java index fa8452c0b43..5dee9b9f099 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java @@ -105,6 +105,7 @@ import com.semmle.ts.ast.ImportWholeDeclaration; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.util.collections.CollectionUtil; import com.semmle.util.data.Pair; import com.semmle.util.trap.TrapWriter; @@ -474,6 +475,11 @@ public class CFGExtractor { return nd.getExpression().accept(this, c); } + @Override + public Node visit(SatisfiesExpr nd, Void c) { + return nd.getExpression().accept(this, c); + } + @Override public Node visit(NonNullAssertion nd, Void c) { return nd.getExpression().accept(this, c); @@ -2028,6 +2034,13 @@ public class CFGExtractor { return null; } + @Override + public Void visit(SatisfiesExpr nd, SuccessorInfo c) { + visitSequence(nd.getExpression(), nd); + writeSuccessors(nd, c.getAllSuccessors()); + return null; + } + @Override public Void visit(NonNullAssertion nd, SuccessorInfo c) { visitSequence(nd.getExpression(), nd); diff --git a/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java b/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java index 9bb5ae766af..17125a9173a 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java @@ -34,6 +34,7 @@ import com.semmle.js.extractor.ASTExtractor.IdContext; import com.semmle.ts.ast.DecoratorList; import com.semmle.ts.ast.ExpressionWithTypeArguments; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.util.exception.CatastrophicError; /** Map from SpiderMonkey expression types to the numeric kinds used in the DB scheme. */ @@ -283,6 +284,11 @@ public class ExprKinds { return nd.isAsExpression() ? 102 : 101; } + @Override + public Integer visit(SatisfiesExpr nd, Void c) { + return 121; + } + @Override public Integer visit(DecoratorList nd, Void c) { return 104; diff --git a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java index 42a41776916..45bd48bf408 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java @@ -104,7 +104,7 @@ public class FileExtractor { /** Information about supported file types. */ public static enum FileType { - HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk") { + HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk", ".html.erb") { @Override public IExtractor mkExtractor(ExtractorConfig config, ExtractorState state) { return new HTMLExtractor(config, state); diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index d03b345af59..69503631c04 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -41,7 +41,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2022-11-08"; + public static final String EXTRACTOR_VERSION = "2022-11-29"; public static final Pattern NEWLINE = Pattern.compile("\n"); diff --git a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java index a1c7b219a8a..82d4e4319c8 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java @@ -10,6 +10,7 @@ import com.semmle.js.ast.TemplateElement; import com.semmle.js.extractor.ASTExtractor.IdContext; import com.semmle.ts.ast.ArrayTypeExpr; import com.semmle.ts.ast.ConditionalTypeExpr; +import com.semmle.js.ast.DynamicImport; import com.semmle.ts.ast.FunctionTypeExpr; import com.semmle.ts.ast.GenericTypeExpr; import com.semmle.ts.ast.ImportTypeExpr; @@ -221,8 +222,7 @@ public class TypeExprKinds { return inferTypeExpr; } - @Override - public Integer visit(ImportTypeExpr nd, Void c) { + private Integer handleInlineImport() { switch (idcontext) { case NAMESPACE_BIND: return importNamespaceAccess; @@ -235,6 +235,17 @@ public class TypeExprKinds { } } + @Override + public Integer visit(ImportTypeExpr nd, Void c) { + return handleInlineImport(); + } + + @Override + public Integer visit(DynamicImport nd, Void c) { + // These may appear in interface 'extend' clauses + return handleInlineImport(); + } + @Override public Integer visit(OptionalTypeExpr nd, Void c) { return optionalTypeExpr; diff --git a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java index d472353067e..7c60a05d33f 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java +++ b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java @@ -119,6 +119,11 @@ public class AutoBuildTests { return CompletableFuture.completedFuture(null); } + @Override + protected boolean hasSeenCode() { + return true; + } + @Override public void verifyTypeScriptInstallation(ExtractorState state) {} diff --git a/javascript/extractor/src/com/semmle/ts/ast/SatisfiesExpr.java b/javascript/extractor/src/com/semmle/ts/ast/SatisfiesExpr.java new file mode 100644 index 00000000000..9ca1d575a68 --- /dev/null +++ b/javascript/extractor/src/com/semmle/ts/ast/SatisfiesExpr.java @@ -0,0 +1,33 @@ +package com.semmle.ts.ast; + +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.SourceLocation; +import com.semmle.js.ast.Visitor; + +/** An expression of form E satisfies T. */ +public class SatisfiesExpr extends Expression { + private final Expression expression; + private final ITypeExpression typeAnnotation; + + public SatisfiesExpr( + SourceLocation loc, + Expression expression, + ITypeExpression typeAnnotation) { + super("SatisfiesExpr", loc); + this.expression = expression; + this.typeAnnotation = typeAnnotation; + } + + public Expression getExpression() { + return expression; + } + + public ITypeExpression getTypeAnnotation() { + return typeAnnotation; + } + + @Override + public R accept(Visitor v, C c) { + return v.visit(this, c); + } +} diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index 1cb1913ee75..cc748054923 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -149,6 +149,7 @@ import com.semmle.ts.ast.TemplateLiteralTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.TypeAssertion; +import com.semmle.ts.ast.SatisfiesExpr; import com.semmle.ts.ast.TypeParameter; import com.semmle.ts.ast.TypeofTypeExpr; import com.semmle.ts.ast.UnaryTypeExpr; @@ -341,6 +342,8 @@ public class TypeScriptASTConverter { return convertArrowFunction(node, loc); case "AsExpression": return convertTypeAssertionExpression(node, loc); + case "SatisfiesExpression": + return convertSatisfiesExpression(node, loc); case "AwaitExpression": return convertAwaitExpression(node, loc); case "BigIntKeyword": @@ -2273,6 +2276,11 @@ public class TypeScriptASTConverter { return new TypeAssertion(loc, convertChild(node, "expression"), type, false); } + private Node convertSatisfiesExpression(JsonObject node, SourceLocation loc) throws ParseError { + ITypeExpression type = convertChildAsType(node, "type"); + return new SatisfiesExpr(loc, convertChild(node, "expression"), type); + } + private Node convertTypeLiteral(JsonObject obj, SourceLocation loc) throws ParseError { return new InterfaceTypeExpr(loc, convertChildren(obj, "members")); } diff --git a/javascript/extractor/tests/ts/input/dynamic-type.ts b/javascript/extractor/tests/ts/input/dynamic-type.ts new file mode 100644 index 00000000000..2b2f90337a2 --- /dev/null +++ b/javascript/extractor/tests/ts/input/dynamic-type.ts @@ -0,0 +1 @@ +interface Foo extends import("foo").Bar {} diff --git a/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap b/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap new file mode 100644 index 00000000000..71410d093cc --- /dev/null +++ b/javascript/extractor/tests/ts/output/trap/dynamic-type.ts.trap @@ -0,0 +1,139 @@ +#10000=@"/dynamic-type.ts;sourcefile" +files(#10000,"/dynamic-type.ts") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +lines(#20002,#20001,"interface Foo extends import(""foo"").Bar {}"," +") +#20003=@"loc,{#10000},1,1,1,42" +locations_default(#20003,#10000,1,1,1,42) +hasLocation(#20002,#20003) +numlines(#20001,1,1,0) +#20004=* +tokeninfo(#20004,7,#20001,0,"interface") +#20005=@"loc,{#10000},1,1,1,9" +locations_default(#20005,#10000,1,1,1,9) +hasLocation(#20004,#20005) +#20006=* +tokeninfo(#20006,6,#20001,1,"Foo") +#20007=@"loc,{#10000},1,11,1,13" +locations_default(#20007,#10000,1,11,1,13) +hasLocation(#20006,#20007) +#20008=* +tokeninfo(#20008,7,#20001,2,"extends") +#20009=@"loc,{#10000},1,15,1,21" +locations_default(#20009,#10000,1,15,1,21) +hasLocation(#20008,#20009) +#20010=* +tokeninfo(#20010,7,#20001,3,"import") +#20011=@"loc,{#10000},1,23,1,28" +locations_default(#20011,#10000,1,23,1,28) +hasLocation(#20010,#20011) +#20012=* +tokeninfo(#20012,8,#20001,4,"(") +#20013=@"loc,{#10000},1,29,1,29" +locations_default(#20013,#10000,1,29,1,29) +hasLocation(#20012,#20013) +#20014=* +tokeninfo(#20014,4,#20001,5,"""foo""") +#20015=@"loc,{#10000},1,30,1,34" +locations_default(#20015,#10000,1,30,1,34) +hasLocation(#20014,#20015) +#20016=* +tokeninfo(#20016,8,#20001,6,")") +#20017=@"loc,{#10000},1,35,1,35" +locations_default(#20017,#10000,1,35,1,35) +hasLocation(#20016,#20017) +#20018=* +tokeninfo(#20018,8,#20001,7,".") +#20019=@"loc,{#10000},1,36,1,36" +locations_default(#20019,#10000,1,36,1,36) +hasLocation(#20018,#20019) +#20020=* +tokeninfo(#20020,6,#20001,8,"Bar") +#20021=@"loc,{#10000},1,37,1,39" +locations_default(#20021,#10000,1,37,1,39) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,8,#20001,9,"{") +#20023=@"loc,{#10000},1,41,1,41" +locations_default(#20023,#10000,1,41,1,41) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,8,#20001,10,"}") +#20025=@"loc,{#10000},1,42,1,42" +locations_default(#20025,#10000,1,42,1,42) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,0,#20001,11,"") +#20027=@"loc,{#10000},2,1,2,0" +locations_default(#20027,#10000,2,1,2,0) +hasLocation(#20026,#20027) +toplevels(#20001,0) +#20028=@"loc,{#10000},1,1,2,0" +locations_default(#20028,#10000,1,1,2,0) +hasLocation(#20001,#20028) +#20029=@"local_type_name;{Foo};{#20000}" +local_type_names(#20029,"Foo",#20000) +#20030=* +stmts(#20030,34,#20001,0,"interfa ... .Bar {}") +hasLocation(#20030,#20003) +stmt_containers(#20030,#20001) +#20031=* +typeexprs(#20031,13,#20030,-1,"import(""foo"").Bar") +#20032=@"loc,{#10000},1,23,1,39" +locations_default(#20032,#10000,1,23,1,39) +hasLocation(#20031,#20032) +enclosing_stmt(#20031,#20030) +expr_containers(#20031,#20001) +#20033=* +typeexprs(#20033,31,#20031,0,"import(""foo"")") +#20034=@"loc,{#10000},1,23,1,35" +locations_default(#20034,#10000,1,23,1,35) +hasLocation(#20033,#20034) +enclosing_stmt(#20033,#20030) +expr_containers(#20033,#20001) +#20035=* +exprs(#20035,4,#20033,0,"""foo""") +hasLocation(#20035,#20015) +enclosing_stmt(#20035,#20030) +expr_containers(#20035,#20001) +literals("foo","""foo""",#20035) +#20036=* +regexpterm(#20036,14,#20035,0,"foo") +#20037=@"loc,{#10000},1,31,1,33" +locations_default(#20037,#10000,1,31,1,33) +hasLocation(#20036,#20037) +regexp_const_value(#20036,"foo") +#20038=* +typeexprs(#20038,15,#20031,1,"Bar") +hasLocation(#20038,#20021) +enclosing_stmt(#20038,#20030) +expr_containers(#20038,#20001) +literals("Bar","Bar",#20038) +#20039=* +typeexprs(#20039,1,#20030,0,"Foo") +hasLocation(#20039,#20007) +enclosing_stmt(#20039,#20030) +expr_containers(#20039,#20001) +literals("Foo","Foo",#20039) +typedecl(#20039,#20029) +#20040=* +entry_cfg_node(#20040,#20001) +#20041=@"loc,{#10000},1,1,1,0" +locations_default(#20041,#10000,1,1,1,0) +hasLocation(#20040,#20041) +#20042=* +exit_cfg_node(#20042,#20001) +hasLocation(#20042,#20027) +successor(#20030,#20042) +successor(#20040,#20030) +numlines(#10000,1,1,0) +filetype(#10000,"typescript") diff --git a/javascript/extractor/tests/vue/input/rails.html.erb b/javascript/extractor/tests/vue/input/rails.html.erb new file mode 100644 index 00000000000..d9df51cf3c0 --- /dev/null +++ b/javascript/extractor/tests/vue/input/rails.html.erb @@ -0,0 +1,3 @@ + diff --git a/javascript/extractor/tests/vue/output/trap/rails.html.erb.trap b/javascript/extractor/tests/vue/output/trap/rails.html.erb.trap new file mode 100644 index 00000000000..76af8c5c8d3 --- /dev/null +++ b/javascript/extractor/tests/vue/output/trap/rails.html.erb.trap @@ -0,0 +1,137 @@ +#10000=@"/rails.erb;sourcefile" +files(#10000,"/rails.erb") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=* +#20002=@"script;{#10000},1,9" +#20003=* +lines(#20003,#20002,""," +") +#20004=@"loc,{#10000},1,9,1,8" +locations_default(#20004,#10000,1,9,1,8) +hasLocation(#20003,#20004) +#20005=* +lines(#20005,#20002," console.log(""FOO"");"," +") +#20006=@"loc,{#10000},2,1,2,21" +locations_default(#20006,#10000,2,1,2,21) +hasLocation(#20005,#20006) +indentation(#10000,2," ",2) +numlines(#20002,2,1,0) +#20007=* +tokeninfo(#20007,6,#20002,0,"console") +#20008=@"loc,{#10000},2,3,2,9" +locations_default(#20008,#10000,2,3,2,9) +hasLocation(#20007,#20008) +#20009=* +tokeninfo(#20009,8,#20002,1,".") +#20010=@"loc,{#10000},2,10,2,10" +locations_default(#20010,#10000,2,10,2,10) +hasLocation(#20009,#20010) +#20011=* +tokeninfo(#20011,6,#20002,2,"log") +#20012=@"loc,{#10000},2,11,2,13" +locations_default(#20012,#10000,2,11,2,13) +hasLocation(#20011,#20012) +#20013=* +tokeninfo(#20013,8,#20002,3,"(") +#20014=@"loc,{#10000},2,14,2,14" +locations_default(#20014,#10000,2,14,2,14) +hasLocation(#20013,#20014) +#20015=* +tokeninfo(#20015,4,#20002,4,"""FOO""") +#20016=@"loc,{#10000},2,15,2,19" +locations_default(#20016,#10000,2,15,2,19) +hasLocation(#20015,#20016) +#20017=* +tokeninfo(#20017,8,#20002,5,")") +#20018=@"loc,{#10000},2,20,2,20" +locations_default(#20018,#10000,2,20,2,20) +hasLocation(#20017,#20018) +#20019=* +tokeninfo(#20019,8,#20002,6,";") +#20020=@"loc,{#10000},2,21,2,21" +locations_default(#20020,#10000,2,21,2,21) +hasLocation(#20019,#20020) +#20021=* +tokeninfo(#20021,0,#20002,7,"") +#20022=@"loc,{#10000},3,1,3,0" +locations_default(#20022,#10000,3,1,3,0) +hasLocation(#20021,#20022) +toplevels(#20002,1) +#20023=@"loc,{#10000},1,9,3,0" +locations_default(#20023,#10000,1,9,3,0) +hasLocation(#20002,#20023) +#20024=* +stmts(#20024,2,#20002,0,"console.log(""FOO"");") +#20025=@"loc,{#10000},2,3,2,21" +locations_default(#20025,#10000,2,3,2,21) +hasLocation(#20024,#20025) +stmt_containers(#20024,#20002) +#20026=* +exprs(#20026,13,#20024,0,"console.log(""FOO"")") +#20027=@"loc,{#10000},2,3,2,20" +locations_default(#20027,#10000,2,3,2,20) +hasLocation(#20026,#20027) +enclosing_stmt(#20026,#20024) +expr_containers(#20026,#20002) +#20028=* +exprs(#20028,14,#20026,-1,"console.log") +#20029=@"loc,{#10000},2,3,2,13" +locations_default(#20029,#10000,2,3,2,13) +hasLocation(#20028,#20029) +enclosing_stmt(#20028,#20024) +expr_containers(#20028,#20002) +#20030=* +exprs(#20030,79,#20028,0,"console") +hasLocation(#20030,#20008) +enclosing_stmt(#20030,#20024) +expr_containers(#20030,#20002) +literals("console","console",#20030) +#20031=@"var;{console};{#20000}" +variables(#20031,"console",#20000) +bind(#20030,#20031) +#20032=* +exprs(#20032,0,#20028,1,"log") +hasLocation(#20032,#20012) +enclosing_stmt(#20032,#20024) +expr_containers(#20032,#20002) +literals("log","log",#20032) +#20033=* +exprs(#20033,4,#20026,0,"""FOO""") +hasLocation(#20033,#20016) +enclosing_stmt(#20033,#20024) +expr_containers(#20033,#20002) +literals("FOO","""FOO""",#20033) +#20034=* +regexpterm(#20034,14,#20033,0,"FOO") +#20035=@"loc,{#10000},2,16,2,18" +locations_default(#20035,#10000,2,16,2,18) +hasLocation(#20034,#20035) +regexp_const_value(#20034,"FOO") +#20036=* +entry_cfg_node(#20036,#20002) +hasLocation(#20036,#20004) +#20037=* +exit_cfg_node(#20037,#20002) +hasLocation(#20037,#20022) +successor(#20024,#20030) +successor(#20033,#20026) +successor(#20032,#20028) +successor(#20030,#20032) +successor(#20028,#20033) +successor(#20026,#20037) +successor(#20036,#20024) +toplevel_parent_xml_node(#20002,#20001) +xmlElements(#20001,"script",#10000,0,#10000) +#20038=@"loc,{#10000},1,1,3,9" +locations_default(#20038,#10000,1,1,3,9) +xmllocations(#20001,#20038) +numlines(#10000,3,1,0) +filetype(#10000,"html") diff --git a/javascript/ql/experimental/adaptivethreatmodeling/README.md b/javascript/ql/experimental/adaptivethreatmodeling/README.md index 341534e3fdf..556d9d94e8f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/README.md +++ b/javascript/ql/experimental/adaptivethreatmodeling/README.md @@ -1,6 +1,8 @@ -# [Internal only] Adaptive Threat Modeling for JavaScript +# Adaptive Threat Modeling for JavaScript This directory contains CodeQL libraries and queries that power adaptive threat modeling for JavaScript. All APIs are experimental and may change in the future. -These queries can only be run by internal users; for external users they will return no results. +Only internal users can run these queries directly. External users can run these queries when performing +JavaScript analysis on Code Scanning. For more information, see +[Code scanning finds more vulnerabilities using machine learning](https://github.blog/2022-02-17-code-scanning-finds-vulnerabilities-using-machine-learning/). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index ba555b0de5b..5532c8d4726 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Configures boosting for adaptive threat modeling (ATM). @@ -6,7 +6,8 @@ private import javascript as JS import EndpointTypes -import EndpointCharacteristics +import EndpointCharacteristics as EndpointCharacteristics +import AdaptiveThreatModeling::ATM::ResultsInfo as AtmResultsInfo /** * EXPERIMENTAL. This API may change in the future. @@ -29,10 +30,23 @@ import EndpointCharacteristics * `isAdditionalFlowStep` with a more generalised definition of additional edges. See * `NosqlInjectionATM.qll` for an example of doing this. */ -abstract class AtmConfig extends string { +abstract class AtmConfig extends JS::TaintTracking::Configuration { bindingset[this] AtmConfig() { any() } + /** + * Holds if `source` is a relevant taint source. When sources are not boosted, `isSource` is equivalent to + * `isKnownSource` (i.e there are no "effective" sources to be classified by an ML model). + */ + override predicate isSource(JS::DataFlow::Node source) { this.isKnownSource(source) } + + /** + * Holds if `sink` is a known taint sink or an "effective" sink (a candidate to be classified by an ML model). + */ + override predicate isSink(JS::DataFlow::Node sink) { + this.isKnownSink(sink) or this.isEffectiveSink(sink) + } + /** * EXPERIMENTAL. This API may change in the future. * @@ -48,9 +62,10 @@ abstract class AtmConfig extends string { 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) + exists(EndpointCharacteristics::EndpointCharacteristic characteristic | + characteristic.appliesToEndpoint(sink) and + characteristic + .hasImplications(this.getASinkEndpointType(), true, characteristic.maximalConfidence()) ) } @@ -68,7 +83,38 @@ abstract class AtmConfig extends string { * Holds if the candidate sink `candidateSink` predicted by the machine learning model should be * an effective sink, i.e. one considered as a possible sink of flow in the boosted query. */ - predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { none() } + predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { + not exists(this.getAReasonSinkExcluded(candidateSink)) + } + + /** + * Gets the list of characteristics that cause `candidateSink` to be excluded as an effective sink. + */ + final EndpointCharacteristics::EndpointCharacteristic getAReasonSinkExcluded( + JS::DataFlow::Node candidateSink + ) { + // An endpoint is an effective sink (sink candidate) if none of its characteristics give much indication whether or + // not it is a sink. Historically, we used endpoint filters, and scored endpoints that are filtered out neither by + // a standard endpoint filter nor by an endpoint filter specific to this sink type. To replicate this behavior, we + // have given the endpoint filter characteristics medium confidence, and we exclude endpoints that have a + // medium-confidence characteristic that indicates that they are not sinks, either in general or for this sink type. + exists(EndpointCharacteristics::EndpointCharacteristic filter, float confidence | + filter.appliesToEndpoint(candidateSink) and + confidence >= filter.mediumConfidence() and + // TODO: Experiment with excluding all endpoints that have a medium- or high-confidence characteristic that + // implies they're not sinks, rather than using only medium-confidence characteristics, by deleting the following + // line. + confidence < filter.highConfidence() and + ( + // Exclude endpoints that have a characteristic that implies they're not sinks for _any_ sink type. + filter.hasImplications(any(NegativeType negative), true, confidence) + or + // Exclude endpoints that have a characteristic that implies they're not sinks for _this particular_ sink type. + filter.hasImplications(this.getASinkEndpointType(), false, confidence) + ) and + result = filter + ) + } /** * EXPERIMENTAL. This API may change in the future. @@ -84,7 +130,7 @@ abstract class AtmConfig extends string { * Get an endpoint type for the sinks of this query. A query may have multiple applicable * endpoint types for its sinks. */ - EndpointType getASinkEndpointType() { none() } + abstract EndpointType getASinkEndpointType(); /** * EXPERIMENTAL. This API may change in the future. @@ -95,6 +141,30 @@ abstract class AtmConfig extends string { * A cut-off value of 1 produces all alerts including those that are likely false-positives. */ float getScoreCutoff() { result = 0.0 } + + /** + * Holds if there's an ATM alert (a flow path from `source` to `sink` with ML-determined likelihood `score`) according + * to this ML-boosted configuration, whereas the unboosted base query does not contain this source and sink + * combination. + */ + predicate hasBoostedFlowPath( + JS::DataFlow::PathNode source, JS::DataFlow::PathNode sink, float score + ) { + this.hasFlowPath(source, sink) and + not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and + score = AtmResultsInfo::getScoreForFlow(source.getNode(), sink.getNode()) + } + + /** + * Holds if if `sink` is an effective sink with flow from `source` which gets used as a sink candidate for scoring + * with the ML model. + */ + predicate isSinkCandidateWithFlow(JS::DataFlow::PathNode sink) { + exists(JS::DataFlow::PathNode source | + this.hasFlowPath(source, sink) and + not AtmResultsInfo::isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) + ) + } } /** DEPRECATED: Alias for AtmConfig */ diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll index 002a5c8fe8e..0168d167509 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides information about the results of boosted queries for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll index a6787196bbb..fb9b017b84c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/BaseScoring.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides shared scoring functionality for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll deleted file mode 100644 index e569fb3dc96..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll +++ /dev/null @@ -1,225 +0,0 @@ -/* - * For internal use only. - * - * Provides predicates that expose the knowledge of models - * in the core CodeQL JavaScript libraries. - */ - -private import javascript -private import semmle.javascript.security.dataflow.XxeCustomizations -private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations -private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations -private import semmle.javascript.security.dataflow.ZipSlipCustomizations -private import semmle.javascript.security.dataflow.TaintedPathCustomizations -private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations -private import semmle.javascript.security.dataflow.XpathInjectionCustomizations -private import semmle.javascript.security.dataflow.Xss::Shared as Xss -private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations -private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.CodeInjectionCustomizations -private import semmle.javascript.security.dataflow.RequestForgeryCustomizations -private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations -private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations -private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations -private import semmle.javascript.security.dataflow.CommandInjectionCustomizations -private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations -private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations -private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations -private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations -private import semmle.javascript.security.dataflow.PostMessageStarCustomizations -private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations -private import semmle.javascript.security.dataflow.SqlInjectionCustomizations -private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations -private import semmle.javascript.security.dataflow.XmlBombCustomizations -private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations -private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations -private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations -private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations -private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations -private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations -private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations -private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations -private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations -private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations -private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations -private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations -private import semmle.javascript.security.dataflow.CleartextStorageCustomizations -import FilteringReasons - -/** - * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. - */ -predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) - ) -} - -/** - * Holds if the node `n` is a known sink for the external API security query. - * - * This corresponds to known sinks from security queries whose sources include remote flow and - * DOM-based sources. - */ -predicate isKnownExternalApiQuerySink(DataFlow::Node n) { - n instanceof Xxe::Sink or - n instanceof TaintedPath::Sink or - n instanceof XpathInjection::Sink or - n instanceof Xss::Sink or - n instanceof ClientSideUrlRedirect::Sink or - n instanceof CodeInjection::Sink or - n instanceof RequestForgery::Sink or - n instanceof CorsMisconfigurationForCredentials::Sink or - n instanceof CommandInjection::Sink or - n instanceof PrototypePollution::Sink or - n instanceof UnvalidatedDynamicMethodCall::Sink or - n instanceof TaintedFormatString::Sink or - n instanceof NosqlInjection::Sink or - n instanceof PostMessageStar::Sink or - n instanceof RegExpInjection::Sink or - n instanceof SqlInjection::Sink or - n instanceof XmlBomb::Sink or - n instanceof ZipSlip::Sink or - n instanceof UnsafeDeserialization::Sink or - n instanceof ServerSideUrlRedirect::Sink or - n instanceof CleartextStorage::Sink or - n instanceof HttpToFileAccess::Sink -} - -/** DEPRECATED: Alias for isKnownExternalApiQuerySink */ -deprecated predicate isKnownExternalAPIQuerySink = isKnownExternalApiQuerySink/1; - -/** - * Holds if the node `n` is a known sink in a modeled library. - */ -predicate isKnownLibrarySink(DataFlow::Node n) { - isKnownExternalApiQuerySink(n) or - n instanceof CleartextLogging::Sink or - n instanceof StackTraceExposure::Sink or - n instanceof ShellCommandInjectionFromEnvironment::Sink or - n instanceof InsecureRandomness::Sink or - n instanceof FileAccessToHttp::Sink or - n instanceof IndirectCommandInjection::Sink -} - -/** - * Holds if the node `n` is known as the predecessor in a modeled flow step. - */ -predicate isKnownStepSrc(DataFlow::Node n) { - TaintTracking::sharedTaintStep(n, _) or - DataFlow::SharedFlowStep::step(n, _) or - DataFlow::SharedFlowStep::step(n, _, _, _) -} - -/** - * Holds if `n` is an argument to a function of a builtin object. - */ -private predicate isArgumentToBuiltinFunction(DataFlow::Node n, FilteringReason reason) { - exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | - ( - builtin instanceof DataFlow::ArrayCreationNode and - reason instanceof ArgumentToArrayReason - or - builtin = - DataFlow::globalVarRef([ - "Map", "Set", "WeakMap", "WeakSet", "Number", "Object", "String", "Array", "Error", - "Math", "Boolean" - ]) and - reason instanceof ArgumentToBuiltinGlobalVarRefReason - ) - | - receiver = [builtin.getAnInvocation(), builtin] and - invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and - invk.getAnArgument() = n - ) - or - exists(Expr primitive, MethodCallExpr c | - primitive instanceof ConstantString or - primitive instanceof NumberLiteral or - primitive instanceof BooleanLiteral - | - c.calls(primitive, _) and - c.getAnArgument() = n.asExpr() and - reason instanceof ConstantReceiverReason - ) - or - exists(DataFlow::CallNode call | - call.getAnArgument() = n and - call.getCalleeName() = - [ - "indexOf", "hasOwnProperty", "substring", "isDecimal", "decode", "encode", "keys", "shift", - "values", "forEach", "toString", "slice", "splice", "push", "isArray", "sort" - ] and - reason instanceof BuiltinCallNameReason - ) -} - -predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) { - isArgumentToBuiltinFunction(n, reason) - or - any(LodashUnderscore::Member m).getACall().getAnArgument() = n and - reason instanceof LodashUnderscoreArgumentReason - or - any(JQuery::MethodCall m).getAnArgument() = n and - reason instanceof JQueryArgumentReason - or - exists(ClientRequest r | - r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode() - ) and - reason instanceof ClientRequestReason - or - exists(PromiseDefinition p | - n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument() - ) and - reason instanceof PromiseDefinitionReason - or - n instanceof CryptographicKey and reason instanceof CryptographicKeyReason - or - any(CryptographicOperation op).getInput() = n and - reason instanceof CryptographicOperationFlowReason - or - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName() = getAStandardLoggerMethodName() and - reason instanceof LoggerMethodReason - or - call.getCalleeName() = ["setTimeout", "clearTimeout"] and - reason instanceof TimeoutReason - or - call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) and - reason instanceof ReceiverStorageReason - or - call instanceof StringOps::StartsWith and reason instanceof StringStartsWithReason - or - call instanceof StringOps::EndsWith and reason instanceof StringEndsWithReason - or - call instanceof StringOps::RegExpTest and reason instanceof StringRegExpTestReason - or - call instanceof EventRegistration and reason instanceof EventRegistrationReason - or - call instanceof EventDispatch and reason instanceof EventDispatchReason - or - call = any(MembershipCandidate c).getTest() and - reason instanceof MembershipCandidateTestReason - or - call instanceof FileSystemAccess and reason instanceof FileSystemAccessReason - or - // TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on existing database models - [ - call, call.getAMethodCall() - /* command pattern where the query is built, and then exec'ed later */ ] instanceof - DatabaseAccess and - reason instanceof DatabaseAccessReason - or - call = DOM::domValueRef() and reason instanceof DomReason - or - call.getCalleeName() = "next" and - exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and - reason instanceof NextFunctionCallReason - or - call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() and - reason instanceof DojoRequireReason - ) - or - (exists(Base64::Decode d | n = d.getInput()) or exists(Base64::Encode d | n = d.getInput())) and - reason instanceof Base64ManipulationReason -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll index adc98a5c08c..e95b2785ceb 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll @@ -7,6 +7,46 @@ 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 +private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics +private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles +private import semmle.javascript.security.dataflow.XxeCustomizations +private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations +private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations +private import semmle.javascript.security.dataflow.ZipSlipCustomizations +private import semmle.javascript.security.dataflow.TaintedPathCustomizations +private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations +private import semmle.javascript.security.dataflow.XpathInjectionCustomizations +private import semmle.javascript.security.dataflow.Xss::Shared as Xss +private import semmle.javascript.security.dataflow.StackTraceExposureCustomizations +private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations +private import semmle.javascript.security.dataflow.RequestForgeryCustomizations +private import semmle.javascript.security.dataflow.CorsMisconfigurationForCredentialsCustomizations +private import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations +private import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassCustomizations +private import semmle.javascript.security.dataflow.CommandInjectionCustomizations +private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations +private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations +private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations +private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations +private import semmle.javascript.security.dataflow.PostMessageStarCustomizations +private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations +private import semmle.javascript.security.dataflow.SqlInjectionCustomizations +private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations +private import semmle.javascript.security.dataflow.XmlBombCustomizations +private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations +private import semmle.javascript.security.dataflow.HardcodedCredentialsCustomizations +private import semmle.javascript.security.dataflow.FileAccessToHttpCustomizations +private import semmle.javascript.security.dataflow.UnsafeDynamicMethodAccessCustomizations +private import semmle.javascript.security.dataflow.UnsafeDeserializationCustomizations +private import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeCustomizations +private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations +private import semmle.javascript.security.dataflow.IndirectCommandInjectionCustomizations +private import semmle.javascript.security.dataflow.ConditionalBypassCustomizations +private import semmle.javascript.security.dataflow.HttpToFileAccessCustomizations +private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations +private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations +private import semmle.javascript.security.dataflow.CleartextStorageCustomizations /** * A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions @@ -25,35 +65,162 @@ abstract class EndpointCharacteristic extends string { * 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); + abstract predicate appliesToEndpoint(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. + * Params: + * endpointClass: The sink type. Each EndpointType has a predicate getEncoding, which specifies the classifier + * class for this sink type. Class 0 is the negative class (non-sink). Each positive int corresponds to a single + * sink type. + * isPositiveIndicator: If true, this characteristic indicates that this endpoint _is_ a member of the class; if + * false, it indicates that it _isn't_ a member of the class. + * confidence: A float in [0, 1], which tells us how strong an indicator this characteristic is for the endpoint + * belonging / not belonging to the given class. A confidence near zero means this characteristic is a very weak + * indicator of whether or not the endpoint belongs to the class. A confidence of 1 means that all endpoints with + * this characteristic definitively do/don't belong to the class. */ - abstract predicate getImplications( + abstract predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ); + + /** Indicators with confidence at or above this threshold are considered to be high-confidence indicators. */ + final float getHighConfidenceThreshold() { result = 0.8 } + + // The following are some confidence values that are used in practice by the subclasses. They are defined as named + // constants here to make it easier to change them in the future. + final float maximalConfidence() { result = 1.0 } + + final float highConfidence() { result = 0.9 } + + final float mediumConfidence() { result = 0.6 } } +/* + * Helper predicates. + */ + +/** + * Holds if the node `n` is a known sink for the external API security query. + * + * This corresponds to known sinks from security queries whose sources include remote flow and + * DOM-based sources. + */ +private predicate isKnownExternalApiQuerySink(DataFlow::Node n) { + n instanceof Xxe::Sink or + n instanceof TaintedPath::Sink or + n instanceof XpathInjection::Sink or + n instanceof Xss::Sink or + n instanceof ClientSideUrlRedirect::Sink or + n instanceof CodeInjection::Sink or + n instanceof RequestForgery::Sink or + n instanceof CorsMisconfigurationForCredentials::Sink or + n instanceof CommandInjection::Sink or + n instanceof PrototypePollution::Sink or + n instanceof UnvalidatedDynamicMethodCall::Sink or + n instanceof TaintedFormatString::Sink or + n instanceof NosqlInjection::Sink or + n instanceof PostMessageStar::Sink or + n instanceof RegExpInjection::Sink or + n instanceof SqlInjection::Sink or + n instanceof XmlBomb::Sink or + n instanceof ZipSlip::Sink or + n instanceof UnsafeDeserialization::Sink or + n instanceof ServerSideUrlRedirect::Sink or + n instanceof CleartextStorage::Sink or + n instanceof HttpToFileAccess::Sink +} + +/** + * Holds if the node `n` is a known sink in a modeled library. + */ +private predicate isKnownLibrarySink(DataFlow::Node n) { + isKnownExternalApiQuerySink(n) or + n instanceof CleartextLogging::Sink or + n instanceof StackTraceExposure::Sink or + n instanceof ShellCommandInjectionFromEnvironment::Sink or + n instanceof InsecureRandomness::Sink or + n instanceof FileAccessToHttp::Sink or + n instanceof IndirectCommandInjection::Sink +} + +/** + * Holds if the node `n` is known as the predecessor in a modeled flow step. + */ +private predicate isKnownStepSrc(DataFlow::Node n) { + TaintTracking::sharedTaintStep(n, _) or + DataFlow::SharedFlowStep::step(n, _) or + DataFlow::SharedFlowStep::step(n, _, _, _) +} + +/** + * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. + * + * This includes direct arguments of likely external library calls as well as nested object + * literals within those calls. + */ +private predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { + n = getACallWithoutCallee().getAnArgument() + or + exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | + n = src.getAPropertyWrite().getRhs() + ) + or + exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | + n = arr.getAnElement() + ) +} + +/** + * Get calls for which we do not have the callee (i.e. the definition of the called function). This + * acts as a heuristic for identifying calls to external library functions. + */ +private DataFlow::CallNode getACallWithoutCallee() { + forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and + not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | + param.flowsTo(result.getCalleeNode()) and + callback = getACallback(param, DataFlow::TypeBackTracker::end()) + ) +} + +/** + * Gets a node that flows to callback-parameter `p`. + */ +private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { + t.start() and + result = p and + any(DataFlow::FunctionNode f).getLastParameter() = p and + exists(p.getACall()) + or + exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) +} + +/** + * Get calls which are likely to be to external non-built-in libraries. + */ +DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } + +/* + * Characteristics that are indicative of a sink. + * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard + * JavaScript libraries. + */ + /** * 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 appliesToEndpoint(DataFlow::Node n) { n instanceof DomBasedXss::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof XssSinkType and isPositiveIndicator = true and confidence = 1.0 + endpointClass instanceof XssSinkType and + isPositiveIndicator = true and + confidence = maximalConfidence() } } @@ -64,12 +231,14 @@ private class DomBasedXssSinkCharacteristic extends EndpointCharacteristic { private class TaintedPathSinkCharacteristic extends EndpointCharacteristic { TaintedPathSinkCharacteristic() { this = "TaintedPathSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof TaintedPath::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof TaintedPath::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { - endpointClass instanceof TaintedPathSinkType and isPositiveIndicator = true and confidence = 1.0 + endpointClass instanceof TaintedPathSinkType and + isPositiveIndicator = true and + confidence = maximalConfidence() } } @@ -80,14 +249,14 @@ private class TaintedPathSinkCharacteristic extends EndpointCharacteristic { private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic { SqlInjectionSinkCharacteristic() { this = "SqlInjectionSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof SqlInjection::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof SqlInjection::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof SqlInjectionSinkType and isPositiveIndicator = true and - confidence = 1.0 + confidence = maximalConfidence() } } @@ -98,13 +267,778 @@ private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic { private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic { NosqlInjectionSinkCharacteristic() { this = "NosqlInjectionSink" } - override predicate getEndpoints(DataFlow::Node n) { n instanceof NosqlInjection::Sink } + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof NosqlInjection::Sink } - override predicate getImplications( + override predicate hasImplications( EndpointType endpointClass, boolean isPositiveIndicator, float confidence ) { endpointClass instanceof NosqlInjectionSinkType and isPositiveIndicator = true and - confidence = 1.0 + confidence = maximalConfidence() + } +} + +/* + * Characteristics that are indicative of not being a sink of any type, and have historically been used to select + * negative samples for training. + */ + +/** + * A characteristic that is an indicator of not being a sink of any type, because it's a modeled argument. + */ +abstract class OtherModeledArgumentCharacteristic extends EndpointCharacteristic { + bindingset[this] + OtherModeledArgumentCharacteristic() { any() } +} + +/** + * A characteristic that is an indicator of not being a sink of any type, because it's an argument to a function of a + * builtin object. + */ +abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherModeledArgumentCharacteristic { + bindingset[this] + ArgumentToBuiltinFunctionCharacteristic() { any() } +} + +/** + * A high-confidence characteristic that indicates that an endpoint is not a sink of any type. + */ +abstract private class NotASinkCharacteristic extends EndpointCharacteristic { + bindingset[this] + NotASinkCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof NegativeType and + isPositiveIndicator = true and + confidence = highConfidence() + } +} + +/** + * A medium-confidence characteristic that indicates that an endpoint is not a sink of any type. + * + * TODO: This class is currently not private, because the current extraction logic explicitly avoids including these + * endpoints in the training data. We might want to change this in the future. + */ +abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic { + bindingset[this] + LikelyNotASinkCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof NegativeType and + isPositiveIndicator = true and + confidence = mediumConfidence() + } +} + +private class LodashUnderscoreCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + LodashUnderscoreCharacteristic() { this = "LodashUnderscoreArgument" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + any(LodashUnderscore::Member m).getACall().getAnArgument() = n + } +} + +private class JQueryArgumentCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + JQueryArgumentCharacteristic() { this = "JQueryArgument" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + any(JQuery::MethodCall m).getAnArgument() = n + } +} + +private class ClientRequestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + ClientRequestCharacteristic() { this = "ClientRequest" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(ClientRequest r | + r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode() + ) + } +} + +private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + PromiseDefinitionCharacteristic() { this = "PromiseDefinition" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(PromiseDefinition p | + n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument() + ) + } +} + +private class CryptographicKeyCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + CryptographicKeyCharacteristic() { this = "CryptographicKey" } + + override predicate appliesToEndpoint(DataFlow::Node n) { n instanceof CryptographicKey } +} + +private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + CryptographicOperationFlowCharacteristic() { this = "CryptographicOperationFlow" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + any(CryptographicOperation op).getInput() = n + } +} + +private class LoggerMethodCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + LoggerMethodCharacteristic() { this = "LoggerMethod" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName() = getAStandardLoggerMethodName() + ) + } +} + +private class TimeoutCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + TimeoutCharacteristic() { this = "Timeout" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName() = ["setTimeout", "clearTimeout"] + ) + } +} + +private class ReceiverStorageCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + ReceiverStorageCharacteristic() { this = "ReceiverStorage" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) + ) + } +} + +private class StringStartsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + StringStartsWithCharacteristic() { this = "StringStartsWith" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call instanceof StringOps::StartsWith + ) + } +} + +private class StringEndsWithCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + StringEndsWithCharacteristic() { this = "StringEndsWith" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof StringOps::EndsWith) + } +} + +private class StringRegExpTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + StringRegExpTestCharacteristic() { this = "StringRegExpTest" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call instanceof StringOps::RegExpTest + ) + } +} + +private class EventRegistrationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + EventRegistrationCharacteristic() { this = "EventRegistration" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventRegistration) + } +} + +private class EventDispatchCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + EventDispatchCharacteristic() { this = "EventDispatch" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventDispatch) + } +} + +private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + MembershipCandidateTestCharacteristic() { this = "MembershipCandidateTest" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call = any(MembershipCandidate c).getTest() + ) + } +} + +private class FileSystemAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + FileSystemAccessCharacteristic() { this = "FileSystemAccess" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof FileSystemAccess) + } +} + +private class DatabaseAccessCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + DatabaseAccessCharacteristic() { this = "DatabaseAccess" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on + // existing database models + exists(DataFlow::CallNode call | n = call.getAnArgument() | + [ + call, call.getAMethodCall() + /* command pattern where the query is built, and then exec'ed later */ ] instanceof + DatabaseAccess + ) + } +} + +private class DomCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic { + DomCharacteristic() { this = "DOM" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call = DOM::domValueRef()) + } +} + +private class NextFunctionCallCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + NextFunctionCallCharacteristic() { this = "NextFunctionCall" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName() = "next" and + exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) + ) + } +} + +private class DojoRequireCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + DojoRequireCharacteristic() { this = "DojoRequire" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() + ) + } +} + +private class Base64ManipulationCharacteristic extends NotASinkCharacteristic, + OtherModeledArgumentCharacteristic { + Base64ManipulationCharacteristic() { this = "Base64Manipulation" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(Base64::Decode d | n = d.getInput()) or + exists(Base64::Encode d | n = d.getInput()) + } +} + +private class ArgumentToArrayCharacteristic extends ArgumentToBuiltinFunctionCharacteristic, + LikelyNotASinkCharacteristic { + ArgumentToArrayCharacteristic() { this = "ArgumentToArray" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | + builtin instanceof DataFlow::ArrayCreationNode + | + receiver = [builtin.getAnInvocation(), builtin] and + invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and + invk.getAnArgument() = n + ) + } +} + +private class ArgumentToBuiltinGlobalVarRefCharacteristic extends ArgumentToBuiltinFunctionCharacteristic, + LikelyNotASinkCharacteristic { + ArgumentToBuiltinGlobalVarRefCharacteristic() { this = "ArgumentToBuiltinGlobalVarRef" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk | + builtin = + DataFlow::globalVarRef([ + "Map", "Set", "WeakMap", "WeakSet", "Number", "Object", "String", "Array", "Error", + "Math", "Boolean" + ]) + | + receiver = [builtin.getAnInvocation(), builtin] and + invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and + invk.getAnArgument() = n + ) + } +} + +private class ConstantReceiverCharacteristic extends ArgumentToBuiltinFunctionCharacteristic, + NotASinkCharacteristic { + ConstantReceiverCharacteristic() { this = "ConstantReceiver" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(Expr primitive, MethodCallExpr c | + primitive instanceof ConstantString or + primitive instanceof NumberLiteral or + primitive instanceof BooleanLiteral + | + c.calls(primitive, _) and + c.getAnArgument() = n.asExpr() + ) + } +} + +private class BuiltinCallNameCharacteristic extends ArgumentToBuiltinFunctionCharacteristic, + NotASinkCharacteristic { + BuiltinCallNameCharacteristic() { this = "BuiltinCallName" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | + call.getAnArgument() = n and + call.getCalleeName() = + [ + "indexOf", "hasOwnProperty", "substring", "isDecimal", "decode", "encode", "keys", + "shift", "values", "forEach", "toString", "slice", "splice", "push", "isArray", "sort" + ] + ) + } +} + +/* + * Characteristics that have historically acted as endpoint filters to exclude endpoints from scoring at inference time. + */ + +/** A characteristic that has historically acted as an endpoint filter for inference-time scoring. */ +abstract class EndpointFilterCharacteristic extends EndpointCharacteristic { + bindingset[this] + EndpointFilterCharacteristic() { any() } +} + +/** + * An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a sink of any type. + */ +abstract private class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + StandardEndpointFilterCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof NegativeType and + isPositiveIndicator = true and + confidence = mediumConfidence() + } +} + +class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic { + IsArgumentToModeledFunctionCharacteristic() { this = "argument to modeled function" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::InvokeNode invk, DataFlow::Node known | + invk.getAnArgument() = n and + invk.getAnArgument() = known and + ( + isKnownLibrarySink(known) + or + isKnownStepSrc(known) + or + exists(OtherModeledArgumentCharacteristic characteristic | + characteristic.appliesToEndpoint(known) + ) + ) + ) + } +} + +private class IsArgumentToSinklessLibraryCharacteristic extends StandardEndpointFilterCharacteristic { + IsArgumentToSinklessLibraryCharacteristic() { this = "argument to sinkless library" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::InvokeNode invk, DataFlow::SourceNode commonSafeLibrary, string libraryName | + libraryName = ["slugify", "striptags", "marked"] + | + commonSafeLibrary = DataFlow::moduleImport(libraryName) and + invk = [commonSafeLibrary, commonSafeLibrary.getAPropertyRead()].getAnInvocation() and + n = invk.getAnArgument() + ) + } +} + +private class IsSanitizerCharacteristic extends StandardEndpointFilterCharacteristic { + IsSanitizerCharacteristic() { this = "sanitizer" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName().regexpMatch("(?i).*(escape|valid(ate)?|sanitize|purify).*") + ) + } +} + +private class IsPredicateCharacteristic extends StandardEndpointFilterCharacteristic { + IsPredicateCharacteristic() { this = "predicate" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName().regexpMatch("(equals|(|is|has|can)(_|[A-Z])).*") + ) + } +} + +private class IsHashCharacteristic extends StandardEndpointFilterCharacteristic { + IsHashCharacteristic() { this = "hash" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + call.getCalleeName().regexpMatch("(?i)^(sha\\d*|md5|hash)$") + ) + } +} + +private class IsNumericCharacteristic extends StandardEndpointFilterCharacteristic { + IsNumericCharacteristic() { this = "numeric" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + SyntacticHeuristics::isReadFrom(n, ".*index.*") + } +} + +private class InIrrelevantFileCharacteristic extends StandardEndpointFilterCharacteristic { + private string category; + + InIrrelevantFileCharacteristic() { + this = "in " + category + " file" and category = ["externs", "generated", "library", "test"] + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // Ignore candidate sinks within externs, generated, library, and test code + ClassifyFiles::classify(n.getFile(), category) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a NoSQL injection sink. */ +abstract private class NosqlInjectionSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + NosqlInjectionSinkEndpointFilterCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof NosqlInjectionSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class DatabaseAccessCallHeuristicCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + DatabaseAccessCallHeuristicCharacteristic() { this = "matches database access call heuristic" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::MethodCallNode call | n = call.getAnArgument() | + // additional databases accesses that aren't modeled yet + call.getMethodName() = ["create", "createCollection", "createIndexes"] + ) + } +} + +private class ModeledSinkCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ModeledSinkCharacteristic() { this = "modeled sink" } + + /** + * Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink. + */ + predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) { + exists(DataFlow::InvokeNode invk, DataFlow::Node known | + invk.getAnArgument() = n and invk.getAnArgument() = known and isKnownLibrarySink(known) + ) + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove modeled sinks + isArgumentToKnownLibrarySinkFunction(n) + ) + } +} + +private class PredecessorInModeledFlowStepCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + PredecessorInModeledFlowStepCharacteristic() { this = "predecessor in a modeled flow step" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove common kinds of unlikely sinks + isKnownStepSrc(n) + ) + } +} + +private class ModeledDatabaseAccessCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ModeledDatabaseAccessCharacteristic() { this = "modeled database access" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove modeled database calls. Arguments to modeled calls are very likely to be modeled + // as sinks if they are true positives. Therefore arguments that are not modeled as sinks + // are unlikely to be true positives. + call instanceof DatabaseAccess + ) + } +} + +private class ReceiverIsHttpRequestExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHttpRequestExpressionCharacteristic() { this = "receiver is a HTTP request expression" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove calls to APIs that aren't relevant to NoSQL injection + call.getReceiver() instanceof Http::RequestNode + ) + } +} + +private class ReceiverIsHttpResponseExpressionCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + ReceiverIsHttpResponseExpressionCharacteristic() { + this = "receiver is a HTTP response expression" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // Remove calls to APIs that aren't relevant to NoSQL injection + call.getReceiver() instanceof Http::ResponseNode + ) + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCharacteristic extends NosqlInjectionSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCharacteristic() { + this = "not a direct argument to a likely external library call or a heuristic sink (nosql)" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // Require NoSQL injection sink candidates to be (a) direct arguments to external library calls + // or (b) heuristic sinks for NoSQL injection. + // + // ## Direct arguments to external library calls + // + // The `flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter + // allows sink candidates which are within object literals or array literals, for example + // `req.sendFile(_, { path: ENDPOINT })`. + // + // However, the NoSQL injection query deals differently with these types of sinks compared to + // other security queries. Other security queries such as SQL injection tend to treat + // `ENDPOINT` as the ground truth sink, but the NoSQL injection query instead treats + // `{ path: ENDPOINT }` as the ground truth sink and defines an additional flow step to ensure + // data flows from `ENDPOINT` to the ground truth sink `{ path: ENDPOINT }`. + // + // Therefore for the NoSQL injection boosted query, we must ignore sink candidates within object + // literals or array literals, to avoid having multiple alerts for the same security + // vulnerability (one FP where the sink is `ENDPOINT` and one TP where the sink is + // `{ path: ENDPOINT }`). We accomplish this by directly testing that the sink candidate is an + // argument of a likely external library call. + // + // ## Heuristic sinks + // + // We also allow heuristic sinks in addition to direct arguments to external library calls. + // These are copied from the `HeuristicNosqlInjectionSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not n = getALikelyExternalLibraryCall().getAnArgument() and + not ( + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(nosql|query)") or + SyntacticHeuristics::isArgTo(n, "(?i)(query)") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a SQL injection sink. */ +abstract private class SqlInjectionSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + SqlInjectionSinkEndpointFilterCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof SqlInjectionSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class PreparedSqlStatementCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + PreparedSqlStatementCharacteristic() { this = "prepared SQL statement" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // prepared statements for SQL + any(DataFlow::CallNode cn | cn.getCalleeName() = "prepare") + .getAMethodCall("run") + .getAnArgument() = n + ) + } +} + +private class ArrayCreationCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + ArrayCreationCharacteristic() { this = "array creation" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + n instanceof DataFlow::ArrayCreationNode + ) + } +} + +private class HtmlOrRenderingCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + HtmlOrRenderingCharacteristic() { this = "HTML / rendering" } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | + // UI is unrelated to SQL + call.getCalleeName().regexpMatch("(?i).*(render|html).*") + ) + } +} + +private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteristic extends SqlInjectionSinkEndpointFilterCharacteristic { + NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteristic() { + this = "not an argument to a likely external library call or a heuristic sink" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // Require SQL injection sink candidates to be (a) arguments to external library calls + // (possibly indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are copied from the `HeuristicSqlInjectionSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(sql|query)") or + SyntacticHeuristics::isArgTo(n, "(?i)(query)") or + SyntacticHeuristics::isConcatenatedWithString(n, + "(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a tainted path injection sink. */ +abstract private class TaintedPathSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + TaintedPathSinkEndpointFilterCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof TaintedPathSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTaintedPathCharacteristic extends TaintedPathSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTaintedPathCharacteristic() { + this = + "not a direct argument to a likely external library call or a heuristic sink (tainted path)" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // Require path injection sink candidates to be (a) arguments to external library calls + // (possibly indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are mostly copied from the `HeuristicTaintedPathSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(file|folder|dir|absolute)") + or + SyntacticHeuristics::isArgTo(n, "(?i)(get|read)file") + or + exists(string pathPattern | + // paths with at least two parts, and either a trailing or leading slash + pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or + pathPattern = "(?i)(/[a-z0-9_.-]+){2,}" + | + SyntacticHeuristics::isConcatenatedWithString(n, pathPattern) + ) + or + SyntacticHeuristics::isConcatenatedWithStrings(".*/", n, "/.*") + or + // In addition to the names from `HeuristicTaintedPathSink` in the + // `isAssignedToOrConcatenatedWith` predicate call above, we also allow the noisier "path" + // name. + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)path") + ) + } +} + +/** An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be an XSS sink. */ +abstract private class XssSinkEndpointFilterCharacteristic extends EndpointFilterCharacteristic { + bindingset[this] + XssSinkEndpointFilterCharacteristic() { any() } + + override predicate hasImplications( + EndpointType endpointClass, boolean isPositiveIndicator, float confidence + ) { + endpointClass instanceof XssSinkType and + isPositiveIndicator = false and + confidence = mediumConfidence() + } +} + +private class SetStateCallsInReactApplicationsCharacteristic extends XssSinkEndpointFilterCharacteristic { + SetStateCallsInReactApplicationsCharacteristic() { + this = "setState calls ought to be safe in react applications" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + exists(DataFlow::CallNode call | n = call.getAnArgument() | call.getCalleeName() = "setState") + } +} + +private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic extends XssSinkEndpointFilterCharacteristic { + NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssCharacteristic() { + this = "not a direct argument to a likely external library call or a heuristic sink (xss)" + } + + override predicate appliesToEndpoint(DataFlow::Node n) { + // Require XSS sink candidates to be (a) arguments to external library calls (possibly + // indirectly), or (b) heuristic sinks. + // + // Heuristic sinks are copied from the `HeuristicDomBasedXssSink` class defined within + // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. + // We can't reuse the class because importing that file would cause us to treat these + // heuristic sinks as known sinks. + not flowsToArgumentOfLikelyExternalLibraryCall(n) and + not ( + SyntacticHeuristics::isAssignedToOrConcatenatedWith(n, "(?i)(html|innerhtml)") + or + SyntacticHeuristics::isArgTo(n, "(?i)(html|render)") + or + n instanceof StringOps::HtmlConcatenationLeaf + or + SyntacticHeuristics::isConcatenatedWithStrings("(?is).*<[a-z ]+.*", n, "(?s).*>.*") + or + // In addition to the heuristic sinks from `HeuristicDomBasedXssSink`, explicitly allow + // property writes like `elem.innerHTML = ` that may not be picked up as HTML + // concatenation leaves. + exists(DataFlow::PropWrite pw | + pw.getPropertyName().regexpMatch("(?i).*html*") and + pw.getRhs() = n + ) + ) } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll index 60a490cc454..8b4d9147a00 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Extracts data about the database for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll index 7f9e53a5465..6746c06db7b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Provides an implementation of scoring alerts for use in adaptive threat modeling (ATM). diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll index aa625b12862..d2cc37b1b33 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointTypes.qll @@ -16,6 +16,11 @@ newtype TEndpointType = abstract class EndpointType extends TEndpointType { abstract string getDescription(); + /** + * Gets the integer representation of this endpoint type. This integer representation specifies the class number + * used by the endpoint scoring model (the classifier) to represent this endpoint type. Class 0 is the negative + * class (non-sink). Each positive int corresponds to a single sink type. + */ abstract int getEncoding(); string toString() { result = getDescription() } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll deleted file mode 100644 index 4b0cdb986e8..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FilteringReasons.qll +++ /dev/null @@ -1,220 +0,0 @@ -/** - * For internal use only. - * - * Defines a set of reasons why a particular endpoint was filtered out. This set of reasons - * contains both reasons why an endpoint could be `NotASink` and reasons why an endpoint could be - * `LikelyNotASink`. The `NotASinkReason`s defined here are exhaustive, but the - * `LikelyNotASinkReason`s are not exhaustive. - */ -newtype TFilteringReason = - TIsArgumentToBuiltinFunctionReason() or - TLodashUnderscoreArgumentReason() or - TClientRequestReason() or - TPromiseDefinitionReason() or - TCryptographicKeyReason() or - TCryptographicOperationFlowReason() or - TLoggerMethodReason() or - TTimeoutReason() or - TReceiverStorageReason() or - TStringStartsWithReason() or - TStringEndsWithReason() or - TStringRegExpTestReason() or - TEventRegistrationReason() or - TEventDispatchReason() or - TMembershipCandidateTestReason() or - TFileSystemAccessReason() or - TDatabaseAccessReason() or - TDomReason() or - TNextFunctionCallReason() or - TArgumentToArrayReason() or - TArgumentToBuiltinGlobalVarRefReason() or - TConstantReceiverReason() or - TBuiltinCallNameReason() or - TBase64ManipulationReason() or - TJQueryArgumentReason() or - TDojoRequireReason() - -/** A reason why a particular endpoint was filtered out by the endpoint filters. */ -abstract class FilteringReason extends TFilteringReason { - abstract string getDescription(); - - abstract int getEncoding(); - - string toString() { result = getDescription() } -} - -/** - * A reason why a particular endpoint might be considered to be `NotASink`. - * - * An endpoint is `NotASink` if it has at least one `NotASinkReason`, it does not have any - * `LikelyNotASinkReason`s, and it is not a known sink. - */ -abstract class NotASinkReason extends FilteringReason { } - -/** - * A reason why a particular endpoint might be considered to be `LikelyNotASink`. - * - * An endpoint is `LikelyNotASink` if it has at least one `LikelyNotASinkReason` and it is not a - * known sink. - */ -abstract class LikelyNotASinkReason extends FilteringReason { } - -class IsArgumentToBuiltinFunctionReason extends NotASinkReason, TIsArgumentToBuiltinFunctionReason { - override string getDescription() { result = "IsArgumentToBuiltinFunction" } - - override int getEncoding() { result = 5 } -} - -class LodashUnderscoreArgumentReason extends NotASinkReason, TLodashUnderscoreArgumentReason { - override string getDescription() { result = "LodashUnderscoreArgument" } - - override int getEncoding() { result = 6 } -} - -class ClientRequestReason extends NotASinkReason, TClientRequestReason { - override string getDescription() { result = "ClientRequest" } - - override int getEncoding() { result = 7 } -} - -class PromiseDefinitionReason extends NotASinkReason, TPromiseDefinitionReason { - override string getDescription() { result = "PromiseDefinition" } - - override int getEncoding() { result = 8 } -} - -class CryptographicKeyReason extends NotASinkReason, TCryptographicKeyReason { - override string getDescription() { result = "CryptographicKey" } - - override int getEncoding() { result = 9 } -} - -class CryptographicOperationFlowReason extends NotASinkReason, TCryptographicOperationFlowReason { - override string getDescription() { result = "CryptographicOperationFlow" } - - override int getEncoding() { result = 10 } -} - -class LoggerMethodReason extends NotASinkReason, TLoggerMethodReason { - override string getDescription() { result = "LoggerMethod" } - - override int getEncoding() { result = 11 } -} - -class TimeoutReason extends NotASinkReason, TTimeoutReason { - override string getDescription() { result = "Timeout" } - - override int getEncoding() { result = 12 } -} - -class ReceiverStorageReason extends NotASinkReason, TReceiverStorageReason { - override string getDescription() { result = "ReceiverStorage" } - - override int getEncoding() { result = 13 } -} - -class StringStartsWithReason extends NotASinkReason, TStringStartsWithReason { - override string getDescription() { result = "StringStartsWith" } - - override int getEncoding() { result = 14 } -} - -class StringEndsWithReason extends NotASinkReason, TStringEndsWithReason { - override string getDescription() { result = "StringEndsWith" } - - override int getEncoding() { result = 15 } -} - -class StringRegExpTestReason extends NotASinkReason, TStringRegExpTestReason { - override string getDescription() { result = "StringRegExpTest" } - - override int getEncoding() { result = 16 } -} - -class EventRegistrationReason extends NotASinkReason, TEventRegistrationReason { - override string getDescription() { result = "EventRegistration" } - - override int getEncoding() { result = 17 } -} - -class EventDispatchReason extends NotASinkReason, TEventDispatchReason { - override string getDescription() { result = "EventDispatch" } - - override int getEncoding() { result = 18 } -} - -class MembershipCandidateTestReason extends NotASinkReason, TMembershipCandidateTestReason { - override string getDescription() { result = "MembershipCandidateTest" } - - override int getEncoding() { result = 19 } -} - -class FileSystemAccessReason extends NotASinkReason, TFileSystemAccessReason { - override string getDescription() { result = "FileSystemAccess" } - - override int getEncoding() { result = 20 } -} - -class DatabaseAccessReason extends NotASinkReason, TDatabaseAccessReason { - override string getDescription() { result = "DatabaseAccess" } - - override int getEncoding() { result = 21 } -} - -class DomReason extends NotASinkReason, TDomReason { - override string getDescription() { result = "DOM" } - - override int getEncoding() { result = 22 } -} - -/** DEPRECATED: Alias for DomReason */ -deprecated class DOMReason = DomReason; - -class NextFunctionCallReason extends NotASinkReason, TNextFunctionCallReason { - override string getDescription() { result = "NextFunctionCall" } - - override int getEncoding() { result = 23 } -} - -class ArgumentToArrayReason extends LikelyNotASinkReason, TArgumentToArrayReason { - override string getDescription() { result = "ArgumentToArray" } - - override int getEncoding() { result = 24 } -} - -class ArgumentToBuiltinGlobalVarRefReason extends LikelyNotASinkReason, - TArgumentToBuiltinGlobalVarRefReason { - override string getDescription() { result = "ArgumentToBuiltinGlobalVarRef" } - - override int getEncoding() { result = 25 } -} - -class ConstantReceiverReason extends NotASinkReason, TConstantReceiverReason { - override string getDescription() { result = "ConstantReceiver" } - - override int getEncoding() { result = 26 } -} - -class BuiltinCallNameReason extends NotASinkReason, TBuiltinCallNameReason { - override string getDescription() { result = "BuiltinCallName" } - - override int getEncoding() { result = 27 } -} - -class Base64ManipulationReason extends NotASinkReason, TBase64ManipulationReason { - override string getDescription() { result = "Base64Manipulation" } - - override int getEncoding() { result = 28 } -} - -class JQueryArgumentReason extends NotASinkReason, TJQueryArgumentReason { - override string getDescription() { result = "JQueryArgument" } - - override int getEncoding() { result = 29 } -} - -class DojoRequireReason extends NotASinkReason, TDojoRequireReason { - override string getDescription() { result = "DojoRequire" } - - override int getEncoding() { result = 30 } -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll index 4464842bc38..62531a9d423 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll @@ -1,4 +1,4 @@ -/* +/** * FunctionBodyFeatures.qll * * Contains logic relating to the `enclosingFunctionBody` and `enclosingFunctionName` features. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 43d74d5334c..e6d602280a4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -1,6 +1,7 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about NoSQL injection vulnerabilities. * Defines shared code used by the NoSQL injection boosted query. */ @@ -8,145 +9,21 @@ import javascript private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations import AdaptiveThreatModeling -private import CoreKnowledge as CoreKnowledge -private import StandardEndpointFilters as StandardEndpointFilters - -module SinkEndpointFilter { - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - // additional databases accesses that aren't modeled yet - call.(DataFlow::MethodCallNode).getMethodName() = - ["create", "createCollection", "createIndexes"] and - result = "matches database access call heuristic" - or - // Remove modeled sinks - CoreKnowledge::isArgumentToKnownLibrarySinkFunction(sinkCandidate) and - result = "modeled sink" - or - // Remove common kinds of unlikely sinks - CoreKnowledge::isKnownStepSrc(sinkCandidate) and - result = "predecessor in a modeled flow step" - or - // Remove modeled database calls. Arguments to modeled calls are very likely to be modeled - // as sinks if they are true positives. Therefore arguments that are not modeled as sinks - // are unlikely to be true positives. - call instanceof DatabaseAccess and - result = "modeled database access" - or - // Remove calls to APIs that aren't relevant to NoSQL injection - call.getReceiver() instanceof Http::RequestNode and - result = "receiver is a HTTP request expression" - or - call.getReceiver() instanceof Http::ResponseNode and - result = "receiver is a HTTP response expression" - ) - or - // Require NoSQL injection sink candidates to be (a) direct arguments to external library calls - // or (b) heuristic sinks for NoSQL injection. - // - // ## Direct arguments to external library calls - // - // The `StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter - // allows sink candidates which are within object literals or array literals, for example - // `req.sendFile(_, { path: ENDPOINT })`. - // - // However, the NoSQL injection query deals differently with these types of sinks compared to - // other security queries. Other security queries such as SQL injection tend to treat - // `ENDPOINT` as the ground truth sink, but the NoSQL injection query instead treats - // `{ path: ENDPOINT }` as the ground truth sink and defines an additional flow step to ensure - // data flows from `ENDPOINT` to the ground truth sink `{ path: ENDPOINT }`. - // - // Therefore for the NoSQL injection boosted query, we must ignore sink candidates within object - // literals or array literals, to avoid having multiple alerts for the same security - // vulnerability (one FP where the sink is `ENDPOINT` and one TP where the sink is - // `{ path: ENDPOINT }`). We accomplish this by directly testing that the sink candidate is an - // argument of a likely external library call. - // - // ## Heuristic sinks - // - // We also allow heuristic sinks in addition to direct arguments to external library calls. - // These are copied from the `HeuristicNosqlInjectionSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not sinkCandidate = StandardEndpointFilters::getALikelyExternalLibraryCall().getAnArgument() and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(nosql|query)") or - isArgTo(sinkCandidate, "(?i)(query)") - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} class NosqlInjectionAtmConfig extends AtmConfig { - NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" } + NosqlInjectionAtmConfig() { this = "NosqlInjectionAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _) } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof NosqlInjectionSinkType } -} -/** DEPRECATED: Alias for NosqlInjectionAtmConfig */ -deprecated class NosqlInjectionATMConfig = NosqlInjectionAtmConfig; - -/** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */ -predicate isBaseAdditionalFlowStep( - DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl -) { - TaintedObject::step(src, trg, inlbl, outlbl) - or - // additional flow step to track taint through NoSQL query objects - inlbl = TaintedObject::label() and - outlbl = TaintedObject::label() and - exists(NoSql::Query query, DataFlow::SourceNode queryObj | - queryObj.flowsTo(query) and - queryObj.flowsTo(trg) and - src = queryObj.getAPropertyWrite().getRhs() - ) -} - -/** - * Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink. - * - * This predicate allows us to propagate data flow through property writes and array constructors - * within a query object, enabling the security query to pick up NoSQL injection vulnerabilities - * involving more complex queries. - */ -DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) { - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(query) and - exists(DataFlow::SourceNode receiver | - receiver = [getASubexpressionWithinQuery(query), query].getALocalSource() - | - result = - [receiver.getAPropertyWrite().getRhs(), receiver.(DataFlow::ArrayCreationNode).getAnElement()] - ) -} - -/** - * A taint-tracking configuration for reasoning about NoSQL injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard NoSQL injection - * query, except additional ATM sinks have been added and the additional flow step has been - * generalised to cover the sinks predicted by ATM. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "NosqlInjectionATM" } - - override predicate isSource(DataFlow::Node source) { source instanceof NosqlInjection::Source } + /* + * This is largely a copy of the taint tracking configuration for the standard NoSQL injection + * query, except additional ATM sinks have been added and the additional flow step has been + * generalised to cover the sinks predicted by ATM. + */ override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { TaintedObject::isSource(source, label) @@ -156,7 +33,7 @@ class Configuration extends TaintTracking::Configuration { sink.(NosqlInjection::Sink).getAFlowLabel() = label or // Allow effective sinks to have any taint label - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(sink) + isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { @@ -175,7 +52,43 @@ class Configuration extends TaintTracking::Configuration { isBaseAdditionalFlowStep(src, trg, inlbl, outlbl) or // relaxed version of previous step to track taint through unmodeled NoSQL query objects - any(NosqlInjectionAtmConfig cfg).isEffectiveSink(trg) and + isEffectiveSink(trg) and src = getASubexpressionWithinQuery(trg) } + + /** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */ + private predicate isBaseAdditionalFlowStep( + DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl + ) { + TaintedObject::step(src, trg, inlbl, outlbl) + or + // additional flow step to track taint through NoSQL query objects + inlbl = TaintedObject::label() and + outlbl = TaintedObject::label() and + exists(NoSql::Query query, DataFlow::SourceNode queryObj | + queryObj.flowsTo(query) and + queryObj.flowsTo(trg) and + src = queryObj.getAPropertyWrite().getRhs() + ) + } + + /** + * Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink. + * + * This predicate allows us to propagate data flow through property writes and array constructors + * within a query object, enabling the security query to pick up NoSQL injection vulnerabilities + * involving more complex queries. + */ + private DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) { + isEffectiveSink(query) and + exists(DataFlow::SourceNode receiver | + receiver = [getASubexpressionWithinQuery(query), query].getALocalSource() + | + result = + [ + receiver.getAPropertyWrite().getRhs(), + receiver.(DataFlow::ArrayCreationNode).getAnElement() + ] + ) + } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll index 3c78a456f21..917e79f401e 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/SqlInjectionATM.qll @@ -1,94 +1,25 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about SQL injection vulnerabilities. * Defines shared code used by the SQL injection boosted query. */ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.SqlInjectionCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters - -/** - * This module provides logic to filter candidate sinks to those which are likely SQL injection - * sinks. - */ -module SinkEndpointFilter { - private import javascript - private import SQL - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - // prepared statements for SQL - any(DataFlow::CallNode cn | cn.getCalleeName() = "prepare") - .getAMethodCall("run") - .getAnArgument() = sinkCandidate and - result = "prepared SQL statement" - or - sinkCandidate instanceof DataFlow::ArrayCreationNode and - result = "array creation" - or - // UI is unrelated to SQL - call.getCalleeName().regexpMatch("(?i).*(render|html).*") and - result = "HTML / rendering" - ) - or - // Require SQL injection sink candidates to be (a) arguments to external library calls - // (possibly indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are copied from the `HeuristicSqlInjectionSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(sql|query)") or - isArgTo(sinkCandidate, "(?i)(query)") or - isConcatenatedWithString(sinkCandidate, - "(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*") - ) and - result = "not an argument to a likely external library call or a heuristic sink" - } -} class SqlInjectionAtmConfig extends AtmConfig { - SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" } + SqlInjectionAtmConfig() { this = "SqlInjectionAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType } -} -/** DEPRECATED: Alias for SqlInjectionAtmConfig */ -deprecated class SqlInjectionATMConfig = SqlInjectionAtmConfig; - -/** - * A taint-tracking configuration for reasoning about SQL injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard SQL injection - * query, except additional sinks have been added using the sink endpoint filter. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjectionATM" } - - override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof SqlInjection::Sink or any(SqlInjectionAtmConfig cfg).isEffectiveSink(sink) - } + /* + * This is largely a copy of the taint tracking configuration for the standard SQL injection + * query, except additional sinks have been added using the sink endpoint filter. + */ override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll deleted file mode 100644 index 38d339a8527..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll +++ /dev/null @@ -1,134 +0,0 @@ -/** - * For internal use only. - * - * Provides classes and predicates that are useful for endpoint filters. - * - * The standard use of this library is to make use of `isPotentialEffectiveSink/1` - */ - -private import javascript -private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles -private import semmle.javascript.heuristics.SyntacticHeuristics -private import CoreKnowledge as CoreKnowledge - -/** Provides a set of reasons why a given data flow node should be excluded as a sink candidate. */ -string getAReasonSinkExcluded(DataFlow::Node n) { - isArgumentToModeledFunction(n) and result = "argument to modeled function" - or - isArgumentToSinklessLibrary(n) and result = "argument to sinkless library" - or - isSanitizer(n) and result = "sanitizer" - or - isPredicate(n) and result = "predicate" - or - isHash(n) and result = "hash" - or - isNumeric(n) and result = "numeric" - or - // Ignore candidate sinks within externs, generated, library, and test code - exists(string category | category = ["externs", "generated", "library", "test"] | - ClassifyFiles::classify(n.getFile(), category) and - result = "in " + category + " file" - ) -} - -/** - * Holds if the node `n` is an argument to a function that has a manual model. - */ -predicate isArgumentToModeledFunction(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::Node known | - invk.getAnArgument() = n and invk.getAnArgument() = known and isSomeModeledArgument(known) - ) -} - -/** - * Holds if the node `n` is an argument that has a manual model. - */ -predicate isSomeModeledArgument(DataFlow::Node n) { - CoreKnowledge::isKnownLibrarySink(n) or - CoreKnowledge::isKnownStepSrc(n) or - CoreKnowledge::isOtherModeledArgument(n, _) -} - -/** - * Holds if `n` appears to be a numeric value. - */ -predicate isNumeric(DataFlow::Node n) { isReadFrom(n, ".*index.*") } - -/** - * Holds if `n` is an argument to a library without sinks. - */ -predicate isArgumentToSinklessLibrary(DataFlow::Node n) { - exists(DataFlow::InvokeNode invk, DataFlow::SourceNode commonSafeLibrary, string libraryName | - libraryName = ["slugify", "striptags", "marked"] - | - commonSafeLibrary = DataFlow::moduleImport(libraryName) and - invk = [commonSafeLibrary, commonSafeLibrary.getAPropertyRead()].getAnInvocation() and - n = invk.getAnArgument() - ) -} - -predicate isSanitizer(DataFlow::Node n) { - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName().regexpMatch("(?i).*(escape|valid(ate)?|sanitize|purify).*") - ) -} - -predicate isPredicate(DataFlow::Node n) { - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName().regexpMatch("(equals|(|is|has|can)(_|[A-Z])).*") - ) -} - -predicate isHash(DataFlow::Node n) { - exists(DataFlow::CallNode call | n = call.getAnArgument() | - call.getCalleeName().regexpMatch("(?i)^(sha\\d*|md5|hash)$") - ) -} - -/** - * Holds if the data flow node is a (possibly indirect) argument of a likely external library call. - * - * This includes direct arguments of likely external library calls as well as nested object - * literals within those calls. - */ -predicate flowsToArgumentOfLikelyExternalLibraryCall(DataFlow::Node n) { - n = getACallWithoutCallee().getAnArgument() - or - exists(DataFlow::SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall(src) | - n = src.getAPropertyWrite().getRhs() - ) - or - exists(DataFlow::ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall(arr) | - n = arr.getAnElement() - ) -} - -/** - * Get calls which are likely to be to external non-built-in libraries. - */ -DataFlow::CallNode getALikelyExternalLibraryCall() { result = getACallWithoutCallee() } - -/** - * Gets a node that flows to callback-parameter `p`. - */ -private DataFlow::SourceNode getACallback(DataFlow::ParameterNode p, DataFlow::TypeBackTracker t) { - t.start() and - result = p and - any(DataFlow::FunctionNode f).getLastParameter() = p and - exists(p.getACall()) - or - exists(DataFlow::TypeBackTracker t2 | result = getACallback(p, t2).backtrack(t2, t)) -} - -/** - * Get calls for which we do not have the callee (i.e. the definition of the called function). This - * acts as a heuristic for identifying calls to external library functions. - */ -private DataFlow::CallNode getACallWithoutCallee() { - forall(Function callee | callee = result.getACallee() | callee.getTopLevel().isExterns()) and - not exists(DataFlow::ParameterNode param, DataFlow::FunctionNode callback | - param.flowsTo(result.getCalleeNode()) and - callback = getACallback(param, DataFlow::TypeBackTracker::end()) - ) -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll index 8b0ce249f89..c494a7587d6 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/TaintedPathATM.qll @@ -1,95 +1,31 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about path injection vulnerabilities. * Defines shared code used by the path injection boosted query. */ import semmle.javascript.heuristics.SyntacticHeuristics import semmle.javascript.security.dataflow.TaintedPathCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters - -/** - * This module provides logic to filter candidate sinks to those which are likely path injection - * sinks. - */ -module SinkEndpointFilter { - private import javascript - private import TaintedPath - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - // Require path injection sink candidates to be (a) arguments to external library calls - // (possibly indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are mostly copied from the `HeuristicTaintedPathSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(file|folder|dir|absolute)") - or - isArgTo(sinkCandidate, "(?i)(get|read)file") - or - exists(string pathPattern | - // paths with at least two parts, and either a trailing or leading slash - pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or - pathPattern = "(?i)(/[a-z0-9_.-]+){2,}" - | - isConcatenatedWithString(sinkCandidate, pathPattern) - ) - or - isConcatenatedWithStrings(".*/", sinkCandidate, "/.*") - or - // In addition to the names from `HeuristicTaintedPathSink` in the - // `isAssignedToOrConcatenatedWith` predicate call above, we also allow the noisier "path" - // name. - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)path") - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} class TaintedPathAtmConfig extends AtmConfig { - TaintedPathAtmConfig() { this = "TaintedPathATMConfig" } + TaintedPathAtmConfig() { this = "TaintedPathAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType } -} -/** DEPRECATED: Alias for TaintedPathAtmConfig */ -deprecated class TaintedPathATMConfig = TaintedPathAtmConfig; - -/** - * A taint-tracking configuration for reasoning about path injection vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard path injection - * query, except additional ATM sinks have been added to the `isSink` predicate. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedPathATM" } - - override predicate isSource(DataFlow::Node source) { source instanceof TaintedPath::Source } + /* + * This is largely a copy of the taint tracking configuration for the standard path injection + * query, except additional ATM sinks have been added to the `isSink` predicate. + */ override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) { label = sink.(TaintedPath::Sink).getAFlowLabel() or // Allow effective sinks to have any taint label - any(TaintedPathAtmConfig cfg).isEffectiveSink(sink) + isEffectiveSink(sink) } override predicate isSanitizer(DataFlow::Node node) { node instanceof TaintedPath::Sanitizer } @@ -115,9 +51,7 @@ class Configuration extends TaintTracking::Configuration { * of barrier guards, we port the barrier guards for the boosted query from the standard library to * sanitizer guards here. */ -class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode { - BarrierGuardNodeAsSanitizerGuardNode() { this instanceof TaintedPath::BarrierGuardNode } - +private class BarrierGuardNodeAsSanitizerGuardNode extends TaintTracking::LabeledSanitizerGuardNode instanceof TaintedPath::BarrierGuardNode { override predicate sanitizes(boolean outcome, Expr e) { blocks(outcome, e) or blocks(outcome, e, _) } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll index cdd49ca302e..d28b669bf49 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssATM.qll @@ -1,95 +1,25 @@ /** * For internal use only. * + * A taint-tracking configuration for reasoning about XSS vulnerabilities. * Defines shared code used by the XSS boosted query. */ private import semmle.javascript.heuristics.SyntacticHeuristics private import semmle.javascript.security.dataflow.DomBasedXssCustomizations import AdaptiveThreatModeling -import CoreKnowledge as CoreKnowledge -import StandardEndpointFilters as StandardEndpointFilters - -/** - * This module provides logic to filter candidate sinks to those which are likely XSS sinks. - */ -module SinkEndpointFilter { - private import javascript - private import DomBasedXss - - /** - * Provides a set of reasons why a given data flow node should be excluded as a sink candidate. - * - * If this predicate has no results for a sink candidate `n`, then we should treat `n` as an - * effective sink. - */ - string getAReasonSinkExcluded(DataFlow::Node sinkCandidate) { - result = StandardEndpointFilters::getAReasonSinkExcluded(sinkCandidate) - or - exists(DataFlow::CallNode call | sinkCandidate = call.getAnArgument() | - call.getCalleeName() = "setState" - ) and - result = "setState calls ought to be safe in react applications" - or - // Require XSS sink candidates to be (a) arguments to external library calls (possibly - // indirectly), or (b) heuristic sinks. - // - // Heuristic sinks are copied from the `HeuristicDomBasedXssSink` class defined within - // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`. - // We can't reuse the class because importing that file would cause us to treat these - // heuristic sinks as known sinks. - not StandardEndpointFilters::flowsToArgumentOfLikelyExternalLibraryCall(sinkCandidate) and - not ( - isAssignedToOrConcatenatedWith(sinkCandidate, "(?i)(html|innerhtml)") - or - isArgTo(sinkCandidate, "(?i)(html|render)") - or - sinkCandidate instanceof StringOps::HtmlConcatenationLeaf - or - isConcatenatedWithStrings("(?is).*<[a-z ]+.*", sinkCandidate, "(?s).*>.*") - or - // In addition to the heuristic sinks from `HeuristicDomBasedXssSink`, explicitly allow - // property writes like `elem.innerHTML = ` that may not be picked up as HTML - // concatenation leaves. - exists(DataFlow::PropWrite pw | - pw.getPropertyName().regexpMatch("(?i).*html*") and - pw.getRhs() = sinkCandidate - ) - ) and - result = "not a direct argument to a likely external library call or a heuristic sink" - } -} class DomBasedXssAtmConfig extends AtmConfig { - DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" } + DomBasedXssAtmConfig() { this = "DomBasedXssAtmConfig" } override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } - override predicate isEffectiveSink(DataFlow::Node sinkCandidate) { - not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)) - } - override EndpointType getASinkEndpointType() { result instanceof XssSinkType } -} -/** DEPRECATED: Alias for DomBasedXssAtmConfig */ -deprecated class DomBasedXssATMConfig = DomBasedXssAtmConfig; - -/** - * A taint-tracking configuration for reasoning about XSS vulnerabilities. - * - * This is largely a copy of the taint tracking configuration for the standard XSSThroughDom query, - * except additional ATM sinks have been added to the `isSink` predicate. - */ -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "DomBasedXssATMConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof DomBasedXss::Source } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof DomBasedXss::Sink or - any(DomBasedXssAtmConfig cfg).isEffectiveSink(sink) - } + /* + * This is largely a copy of the taint tracking configuration for the standard XSSThroughDom query, + * except additional ATM sinks have been added to the `isSink` predicate. + */ override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll new file mode 100644 index 00000000000..87d69a37165 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/XssThroughDomATM.qll @@ -0,0 +1,88 @@ +/** + * For internal use only. + * + * A taint-tracking configuration for reasoning about XSS through the DOM. + * Defines shared code used by the XSS Through DOM boosted query. + */ + +private import semmle.javascript.heuristics.SyntacticHeuristics +private import semmle.javascript.security.dataflow.DomBasedXssCustomizations +private import semmle.javascript.dataflow.InferredTypes +private import semmle.javascript.security.dataflow.XssThroughDomCustomizations::XssThroughDom as XssThroughDom +private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQuery +import AdaptiveThreatModeling + +class XssThroughDomAtmConfig extends AtmConfig { + XssThroughDomAtmConfig() { this = "XssThroughDomAtmConfig" } + + override predicate isKnownSource(DataFlow::Node source) { + source instanceof XssThroughDom::Source + } + + override EndpointType getASinkEndpointType() { result instanceof XssSinkType } + + override predicate isSanitizer(DataFlow::Node node) { + super.isSanitizer(node) or + node instanceof DomBasedXss::Sanitizer + } + + override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) { + guard instanceof TypeTestGuard or + guard instanceof UnsafeJQuery::PropertyPresenceSanitizer or + guard instanceof UnsafeJQuery::NumberGuard or + guard instanceof PrefixStringSanitizer or + guard instanceof QuoteGuard or + guard instanceof ContainsHtmlGuard + } + + override predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) { + DomBasedXss::isOptionallySanitizedEdge(pred, succ) + } +} + +/** + * A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. + * + * This sanitizer helps prune infeasible paths in type-overloaded functions. + */ +class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + override EqualityTest astNode; + Expr operand; + boolean polarity; + + TypeTestGuard() { + exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) | + // typeof x === "string" sanitizes `x` when it evaluates to false + tag = "string" and + polarity = astNode.getPolarity().booleanNot() + or + // typeof x === "object" sanitizes `x` when it evaluates to true + tag != "string" and + polarity = astNode.getPolarity() + ) + } + + override predicate sanitizes(boolean outcome, Expr e) { + polarity = outcome and + e = operand + } +} + +private import semmle.javascript.security.dataflow.Xss::Shared as Shared + +private class PrefixStringSanitizer extends TaintTracking::SanitizerGuardNode, + DomBasedXss::PrefixStringSanitizer { + PrefixStringSanitizer() { this = this } +} + +private class PrefixString extends DataFlow::FlowLabel, DomBasedXss::PrefixString { + PrefixString() { this = this } +} + +private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard { + QuoteGuard() { this = this } +} + +private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard { + ContainsHtmlGuard() { this = this } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml index e0571f38255..9e722f81eae 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml @@ -1,5 +1,6 @@ name: codeql/javascript-experimental-atm-lib -version: 0.4.1 +description: CodeQL libraries for the experimental ML-powered queries +version: 0.4.5 extractor: javascript library: true groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml index 40b611fc72a..e37547ed938 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-model +description: Machine learning model supporting the experimental ML-powered queries version: 0.3.1 groups: - javascript diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql index 28a95268a57..ac2f2f1d817 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/DebugResultInclusion.ql @@ -11,20 +11,28 @@ import javascript import experimental.adaptivethreatmodeling.ATMConfig -import extraction.ExtractEndpointData +import extraction.ExtractEndpointDataTraining +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) { query instanceof NosqlInjectionQuery and - result = NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(NosqlInjectionAtm::NosqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof SqlInjectionQuery and - result = SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(SqlInjectionAtm::SqlInjectionAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof TaintedPathQuery and - result = TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(TaintedPathAtm::TaintedPathAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) or query instanceof XssQuery and - result = XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate) + result = any(XssAtm::DomBasedXssAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) + or + query instanceof XssThroughDomQuery and + result = any(XssThroughDomAtm::XssThroughDomAtmConfig cfg).getAReasonSinkExcluded(sinkCandidate) } pragma[inline] @@ -33,7 +41,7 @@ string getDescriptionForAlertCandidate( ) { result = "excluded[reason=" + getAReasonSinkExcluded(sinkCandidate, query) + "]" or - getAtmCfg(query).isKnownSink(sinkCandidate) and + getDataFlowCfg(query).(AtmConfig).isKnownSink(sinkCandidate) and result = "excluded[reason=known-sink]" or not exists(getAReasonSinkExcluded(sinkCandidate, query)) and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll index 2549db106f4..a4f52b1cf78 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/counting/CountAlertsAndSinks.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll index 79d3486e2db..822b2d7ea62 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Exclusions.qll @@ -1,4 +1,4 @@ -/* +/** * For internal use only. * * Defines files that should be excluded from the evaluation of ML models. diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql deleted file mode 100644 index 73dab4af324..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.ql +++ /dev/null @@ -1,11 +0,0 @@ -/* - * For internal use only. - * - * Extracts training and evaluation data we can use to train ML models for ML-powered queries. - */ - -import ExtractEndpointData as ExtractEndpointData - -query predicate endpoints = ExtractEndpointData::endpoints/5; - -query predicate tokenFeatures = ExtractEndpointData::tokenFeatures/3; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll deleted file mode 100644 index af91933b7a4..00000000000 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll +++ /dev/null @@ -1,215 +0,0 @@ -/* - * For internal use only. - * - * Library code for training and evaluation data we can use to train ML models for ML-powered - * queries. - */ - -import javascript -import Exclusions as Exclusions -import evaluation.EndToEndEvaluation as EndToEndEvaluation -import experimental.adaptivethreatmodeling.ATMConfig -import experimental.adaptivethreatmodeling.CoreKnowledge as CoreKnowledge -import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures -import experimental.adaptivethreatmodeling.EndpointScoring as EndpointScoring -import experimental.adaptivethreatmodeling.EndpointTypes -import experimental.adaptivethreatmodeling.FilteringReasons -import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm - -/** DEPRECATED: Alias for NosqlInjectionAtm */ -deprecated module NosqlInjectionATM = NosqlInjectionAtm; - -import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm - -/** DEPRECATED: Alias for SqlInjectionAtm */ -deprecated module SqlInjectionATM = SqlInjectionAtm; - -import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm - -/** DEPRECATED: Alias for TaintedPathAtm */ -deprecated module TaintedPathATM = TaintedPathAtm; - -import experimental.adaptivethreatmodeling.XssATM as XssAtm - -/** DEPRECATED: Alias for XssAtm */ -deprecated module XssATM = XssAtm; - -import Labels -import NoFeaturizationRestrictionsConfig -import Queries - -/** Gets the ATM configuration object for the specified query. */ -AtmConfig getAtmCfg(Query query) { - query instanceof NosqlInjectionQuery and - result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig - or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::SqlInjectionAtmConfig - or - query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig - or - query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig -} - -/** DEPRECATED: Alias for getAtmCfg */ -deprecated ATMConfig getATMCfg(Query query) { result = getAtmCfg(query) } - -/** Gets the ATM data flow configuration for the specified query. */ -DataFlow::Configuration getDataFlowCfg(Query query) { - query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::Configuration - or - query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::Configuration - or - query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::Configuration - or - query instanceof XssQuery and result instanceof XssAtm::Configuration -} - -/** Gets a known sink for the specified query. */ -private DataFlow::Node getASink(Query query) { - getAtmCfg(query).isKnownSink(result) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** Gets a data flow node that is known not to be a sink for the specified query. */ -private DataFlow::Node getANotASink(NotASinkReason reason) { - CoreKnowledge::isOtherModeledArgument(result, reason) and - // Some endpoints can be assigned both a `NotASinkReason` and a `LikelyNotASinkReason`. We - // consider these endpoints to be `LikelyNotASink`, therefore this line excludes them from the - // definition of `NotASink`. - not CoreKnowledge::isOtherModeledArgument(result, any(LikelyNotASinkReason t)) and - not result = getASink(_) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** - * Gets a data flow node whose label is unknown for the specified query. - * - * In other words, this is an endpoint that is not `Sink`, `NotASink`, or `LikelyNotASink` for the - * specified query. - */ -private DataFlow::Node getAnUnknown(Query query) { - getAtmCfg(query).isEffectiveSink(result) and - // Effective sinks should exclude sinks but this is a defensive requirement - not result = getASink(query) and - // Effective sinks should exclude NotASink but for some queries (e.g. Xss) this is currently not always the case and - // so this is a defensive requirement - not result = getANotASink(_) and - // Only consider the source code for the project being analyzed. - exists(result.getFile().getRelativePath()) -} - -/** Gets the query-specific sink label for the given endpoint, if such a label exists. */ -private EndpointLabel getSinkLabelForEndpoint(DataFlow::Node endpoint, Query query) { - endpoint = getASink(query) and result instanceof SinkLabel - or - endpoint = getANotASink(_) and result instanceof NotASinkLabel - or - endpoint = getAnUnknown(query) and result instanceof UnknownLabel -} - -/** Gets an endpoint that should be extracted. */ -DataFlow::Node getAnEndpoint(Query query) { exists(getSinkLabelForEndpoint(result, query)) } - -/** - * Endpoints and associated metadata. - * - * Note that we draw a distinction between _features_, that are provided to the model at training - * and query time, and _metadata_, that is only provided to the model at training time. - * - * Internal: See the design document for - * [extensible extraction queries](https://docs.google.com/document/d/1g3ci2Nf1hGMG6ZUP0Y4PqCy_8elcoC_dhBvgTxdAWpg) - * for technical information about the design of this predicate. - */ -predicate endpoints( - DataFlow::Node endpoint, string queryName, string key, string value, string valueType -) { - exists(Query query | - // Only provide metadata for labelled endpoints, since we do not extract all endpoints. - endpoint = getAnEndpoint(query) and - queryName = query.getName() and - ( - // Holds if there is a taint flow path from a known source to the endpoint - key = "hasFlowFromSource" and - ( - if FlowFromSource::hasFlowFromSource(endpoint, query) - then value = "true" - else value = "false" - ) and - valueType = "boolean" - or - // Constant expressions always evaluate to a constant primitive value. Therefore they can't ever - // appear in an alert, making them less interesting training examples. - key = "isConstantExpression" and - (if endpoint.asExpr() instanceof ConstantExpr then value = "true" else value = "false") and - valueType = "boolean" - or - // Holds if alerts involving the endpoint are excluded from the end-to-end evaluation. - key = "isExcludedFromEndToEndEvaluation" and - (if Exclusions::isFileExcluded(endpoint.getFile()) then value = "true" else value = "false") and - valueType = "boolean" - or - // The label for this query, considering the endpoint as a sink. - key = "sinkLabel" and - value = getSinkLabelForEndpoint(endpoint, query).getEncoding() and - valueType = "string" - or - // The reason, or reasons, why the endpoint was labeled NotASink for this query. - key = "notASinkReason" and - exists(FilteringReason reason | - endpoint = getANotASink(reason) and - value = reason.getDescription() - ) and - valueType = "string" - ) - ) -} - -/** - * `EndpointFeatures::tokenFeatures` has no results when `featureName` is absent for the endpoint - * `endpoint`. To preserve compatibility with the data pipeline, this relation will instead set - * `featureValue` to the empty string in this case. - */ -predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { - endpoints(endpoint, _, _, _, _) and - ( - EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) - or - // Performance note: this creates a Cartesian product between `endpoint` and `featureName`. - featureName = EndpointFeatures::getASupportedFeatureName() and - not exists(string value | EndpointFeatures::tokenFeatures(endpoint, featureName, value)) and - featureValue = "" - ) -} - -module FlowFromSource { - predicate hasFlowFromSource(DataFlow::Node endpoint, Query q) { - exists(Configuration cfg | cfg.getQuery() = q | cfg.hasFlow(_, endpoint)) - } - - /** - * A data flow configuration that replicates the data flow configuration for a specific query, but - * replaces the set of sinks with the set of endpoints we're extracting. - * - * We use this to find out when there is flow to a particular endpoint from a known source. - * - * This configuration behaves in a very similar way to the `ForwardExploringConfiguration` class - * from the CodeQL standard libraries for JavaScript. - */ - private class Configuration extends DataFlow::Configuration { - Query q; - - Configuration() { this = getDataFlowCfg(q) } - - Query getQuery() { result = q } - - /** Holds if `sink` is an endpoint we're extracting. */ - override predicate isSink(DataFlow::Node sink) { sink = getAnEndpoint(q) } - - /** Holds if `sink` is an endpoint we're extracting. */ - override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) { - sink = getAnEndpoint(q) and exists(lbl) - } - } -} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql index 20ece497585..3b0bb468ffd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.ql @@ -4,23 +4,8 @@ * Extracts training data we can use to train ML models for ML-powered queries. */ -import javascript -import ExtractEndpointData as ExtractEndpointData +private import ExtractEndpointDataTraining as ExtractEndpointDataTraining -query predicate endpoints( - DataFlow::Node endpoint, string queryName, string key, string value, string valueType -) { - ExtractEndpointData::endpoints(endpoint, queryName, key, value, valueType) and - // only select endpoints that are either Sink or NotASink - ExtractEndpointData::endpoints(endpoint, queryName, "sinkLabel", ["Sink", "NotASink"], "string") and - // do not select endpoints filtered out by end-to-end evaluation - ExtractEndpointData::endpoints(endpoint, queryName, "isExcludedFromEndToEndEvaluation", "false", - "boolean") and - // only select endpoints that can be part of a tainted flow - ExtractEndpointData::endpoints(endpoint, queryName, "isConstantExpression", "false", "boolean") -} +query predicate endpoints = ExtractEndpointDataTraining::reformattedTrainingEndpoints/5; -query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { - endpoints(endpoint, _, _, _, _) and - ExtractEndpointData::tokenFeatures(endpoint, featureName, featureValue) -} +query predicate tokenFeatures = ExtractEndpointDataTraining::tokenFeatures/3; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll new file mode 100644 index 00000000000..763c74c7cf3 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointDataTraining.qll @@ -0,0 +1,250 @@ +/** + * For internal use only. + * + * Extracts training data we can use to train ML models for ML-powered queries. + */ + +import javascript +import experimental.adaptivethreatmodeling.EndpointCharacteristics +import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures +import NoFeaturizationRestrictionsConfig +private import Exclusions as Exclusions +import Queries +private import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm +private import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm +private import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm +private import experimental.adaptivethreatmodeling.XssATM as XssAtm +private import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm + +/** + * Gets the set of featureName-featureValue pairs for each endpoint in the training set. + * + * `EndpointFeatures::tokenFeatures` has no results when `featureName` is absent for the endpoint + * `endpoint`. To preserve compatibility with the data pipeline, this relation will instead set + * `featureValue` to the empty string in this case. + */ +predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) { + trainingEndpoints(endpoint, _, _) and + ( + EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue) + or + // Performance note: this creates a Cartesian product between `endpoint` and `featureName`. + featureName = EndpointFeatures::getASupportedFeatureName() and + not exists(string value | EndpointFeatures::tokenFeatures(endpoint, featureName, value)) and + featureValue = "" + ) +} + +/** + * Holds if the given endpoint should be included in the training set as a sample belonging to endpointClass, and has + * the given characteristic. This query uses the endpoint characteristics to select and label endpoints for the training + * set, and provides a list of characteristics for each endpoint in the training set, which is used in the modeling + * code. + * + * Params: + * endpoint: The endpoint to include / exclude. + * endpointClass: The sink type. See the documentation of EndpointType.getEncoding for details about the relationship + * between an EndpointType and a class in the classifier. + * characteristic: Provides the list of characteristics that apply to the endpoint, which the modeling code currently + * uses for type balancing. + * + * Note: This predicate will produce multiple tuples for endpoints that have multiple characteristics, which we must + * then group together into a list of characteristics. + */ +query predicate trainingEndpoints( + DataFlow::Node endpoint, EndpointType endpointClass, EndpointCharacteristic characteristic +) { + characteristic.appliesToEndpoint(endpoint) and + // Only consider the source code for the project being analyzed. + exists(endpoint.getFile().getRelativePath()) and + // Only select endpoints that can be part of a tainted flow: Constant expressions always evaluate to a constant + // primitive value. Therefore they can't ever appear in an alert, making them less interesting training examples. + // TODO: Experiment with removing this requirement. + not endpoint.asExpr() instanceof ConstantExpr and + // Do not select endpoints filtered out by end-to-end evaluation. + // TODO: Experiment with removing this requirement. + not Exclusions::isFileExcluded(endpoint.getFile()) and + // Filter out negative examples that also have a LikelyNotASinkReason, because this is currently done here + // https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointData.qll#L77 + // TODO: Experiment with removing this requirement. + not ( + endpointClass instanceof NegativeType and + exists(EndpointCharacteristic c | + c.appliesToEndpoint(endpoint) and + c instanceof LikelyNotASinkCharacteristic + ) + ) and + // Don't surface endpoint filters as characteristics, because they were previously not surfaced. + // TODO: Experiment with surfacing these to the modeling code by removing the following line (and then make + // EndpointFilterCharacteristic private). + not characteristic instanceof EndpointFilterCharacteristic and + ( + // If the list of characteristics includes positive indicators with high confidence for this class, select this as a + // training sample belonging to the class. + exists(EndpointCharacteristic characteristic2, float confidence | + characteristic2.appliesToEndpoint(endpoint) and + characteristic2.hasImplications(endpointClass, true, confidence) and + confidence >= characteristic2.getHighConfidenceThreshold() + ) and + ( + // Temporarily limit this only to positive classes. For negative classes, additionally select only endpoints that + // have no high confidence indicators that they are sinks, because this is what was previously done. + // TODO: Experiment with removing this requirement, and instead ensuring that an endpoint never has both a high + // confidence indicator that it _is_ a sink and a high confidence indicator that it is _not_ a sink. + not endpointClass instanceof NegativeType + or + not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | + characteristic3.appliesToEndpoint(endpoint) and + characteristic3.hasImplications(posClass, true, confidence3) and + confidence3 >= characteristic3.getHighConfidenceThreshold() and + not posClass instanceof NegativeType + ) + ) + or + // If the list of characteristics includes negative indicators with high confidence for all classes other than 0, + // select this as a training sample of class 0 (this means we had query-specific characteristics to decide this + // endpoint isn't a sink for each of our sink types). + endpointClass instanceof NegativeType and + forall(EndpointType otherClass | not otherClass instanceof NegativeType | + exists(EndpointCharacteristic characteristic2, float confidence | + characteristic2.appliesToEndpoint(endpoint) and + characteristic2.hasImplications(otherClass, false, confidence) and + confidence >= characteristic2.getHighConfidenceThreshold() + ) + ) + ) +} + +/** + * Temporary: + * Reformat the training data that was extracted with the new logic to match the format produced by the old predicate. + * This is the format expected by the endpoint pipeline. + */ +query predicate reformattedTrainingEndpoints( + DataFlow::Node endpoint, string queryName, string key, string value, string valueType +) { + trainingEndpoints(endpoint, _, _) and + exists(Query query | + queryName = query.getName() and + // For sinks, only list that sink type, but for non-sinks, list all sink types. + ( + exists(EndpointType endpointClass | + endpointClass.getDescription().matches(queryName + "%") and + not endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + exists(EndpointType endpointClass | + endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + ) and + ( + // NOTE: We don't use hasFlowFromSource in training, so we could just hardcode it to be false. + key = "hasFlowFromSource" and + ( + if FlowFromSource::hasFlowFromSource(endpoint, query) + then value = "true" + else value = "false" + ) and + valueType = "boolean" + or + // Constant expressions always evaluate to a constant primitive value. Therefore they can't ever + // appear in an alert, making them less interesting training examples. + key = "isConstantExpression" and + (if endpoint.asExpr() instanceof ConstantExpr then value = "true" else value = "false") and + valueType = "boolean" + or + // Holds if alerts involving the endpoint are excluded from the end-to-end evaluation. + key = "isExcludedFromEndToEndEvaluation" and + (if Exclusions::isFileExcluded(endpoint.getFile()) then value = "true" else value = "false") and + valueType = "boolean" + or + // The label for this query, considering the endpoint as a sink. + key = "sinkLabel" and + valueType = "string" and + value = "Sink" and + exists(EndpointType endpointClass | + endpointClass.getDescription().matches(queryName + "%") and + not endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + key = "sinkLabel" and + valueType = "string" and + value = "NotASink" and + exists(EndpointType endpointClass | + endpointClass instanceof NegativeType and + trainingEndpoints(endpoint, endpointClass, _) + ) + or + // The reason, or reasons, why the endpoint was labeled NotASink for this query, only for negative examples. + key = "notASinkReason" and + exists(EndpointCharacteristic characteristic, EndpointType endpointClass | + characteristic.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointClass, true, _) and + endpointClass instanceof NegativeType and + value = characteristic + ) and + // Don't include a notASinkReason for endpoints that are also known sinks. + not exists(EndpointCharacteristic characteristic3, float confidence3, EndpointType posClass | + characteristic3.appliesToEndpoint(endpoint) and + characteristic3.hasImplications(posClass, true, confidence3) and + confidence3 >= characteristic3.getHighConfidenceThreshold() and + not posClass instanceof NegativeType + ) and + // Don't surface endpoint filters as notASinkReasons, because they were previously not surfaced. + // TODO: Experiment with surfacing these to the modeling code by removing the following line (and then make + // EndpointFilterCharacteristic private). + not value instanceof EndpointFilterCharacteristic and + valueType = "string" + ) + ) +} + +/** + * Gets the ATM data flow configuration for the specified query. + * TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. + */ +DataFlow::Configuration getDataFlowCfg(Query query) { + query instanceof NosqlInjectionQuery and + result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig + or + query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::SqlInjectionAtmConfig + or + query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig + or + query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig + or + query instanceof XssThroughDomQuery and result instanceof XssThroughDomAtm::XssThroughDomAtmConfig +} + +// TODO: Delete this once we are no longer surfacing `hasFlowFromSource`. +private module FlowFromSource { + predicate hasFlowFromSource(DataFlow::Node endpoint, Query q) { + exists(Configuration cfg | cfg.getQuery() = q | cfg.hasFlow(_, endpoint)) + } + + /** + * A data flow configuration that replicates the data flow configuration for a specific query, but + * replaces the set of sinks with the set of endpoints we're extracting. + * + * We use this to find out when there is flow to a particular endpoint from a known source. + * + * This configuration behaves in a very similar way to the `ForwardExploringConfiguration` class + * from the CodeQL standard libraries for JavaScript. + */ + private class Configuration extends DataFlow::Configuration { + Query q; + + Configuration() { this = getDataFlowCfg(q) } + + Query getQuery() { result = q } + + /** Holds if `sink` is an endpoint we're extracting. */ + override predicate isSink(DataFlow::Node sink) { any() } + + /** Holds if `sink` is an endpoint we're extracting. */ + override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) { exists(lbl) } + } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql index 697928d74b0..57c536eac12 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractEndpointMapping.ql @@ -8,6 +8,7 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm import experimental.adaptivethreatmodeling.XssATM as XssAtm +import experimental.adaptivethreatmodeling.XssThroughDomATM as XssThroughDomAtm import experimental.adaptivethreatmodeling.AdaptiveThreatModeling from string queryName, AtmConfig c, EndpointType e @@ -23,6 +24,8 @@ where c instanceof TaintedPathAtm::TaintedPathAtmConfig or queryName = "Xss" and c instanceof XssAtm::DomBasedXssAtmConfig + or + queryName = "XssThroughDom" and c instanceof XssThroughDomAtm::XssThroughDomAtmConfig ) and e = c.getASinkEndpointType() select queryName, e.getEncoding() as label diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll index 51dd3ffec84..a75e01b99cd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/Queries.qll @@ -8,7 +8,8 @@ newtype TQuery = TNosqlInjectionQuery() or TSqlInjectionQuery() or TTaintedPathQuery() or - TXssQuery() + TXssQuery() or + TXssThroughDomQuery() abstract class Query extends TQuery { abstract string getName(); @@ -31,3 +32,7 @@ class TaintedPathQuery extends Query, TTaintedPathQuery { class XssQuery extends Query, TXssQuery { override string getName() { result = "Xss" } } + +class XssThroughDomQuery extends Query, TXssThroughDomQuery { + override string getName() { result = "XssThroughDom" } +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml index e6657138f1c..ac65fc1bb5f 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml @@ -1,4 +1,5 @@ name: codeql/javascript-experimental-atm-model-building +description: CodeQL libraries for building machine learning models for the experimental ML-powered queries extractor: javascript library: false groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql index e35653fb96a..6d5428f7c91 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/NosqlInjectionATM.ql @@ -17,11 +17,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.NosqlInjectionATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql index b58dd9f4609..fdeb79de145 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/SqlInjectionATM.ql @@ -17,11 +17,8 @@ import experimental.adaptivethreatmodeling.SqlInjectionATM import ATM::ResultsInfo import DataFlow::PathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a database query that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql index 7e637687d75..b505a381971 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/TaintedPathATM.ql @@ -21,11 +21,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.TaintedPathATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a path that depends on $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql index d0e98c1cd54..449f450f3ce 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssATM.ql @@ -18,11 +18,8 @@ import ATM::ResultsInfo import DataFlow::PathGraph import experimental.adaptivethreatmodeling.XssATM -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score -where - cfg.hasFlowPath(source, sink) and - not isFlowLikelyInBaseQuery(source.getNode(), sink.getNode()) and - score = getScoreForFlow(source.getNode(), sink.getNode()) +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.hasBoostedFlowPath(source, sink, score) select sink.getNode(), source, sink, "(Experimental) This may be a cross-site scripting vulnerability due to $@. Identified using machine learning.", source.getNode(), "a user-provided value", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql new file mode 100644 index 00000000000..494b308893f --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/XssThroughDomATM.ql @@ -0,0 +1,25 @@ +/** + * For internal use only. + * + * @name DOM text reinterpreted as HTML (experimental) + * @description Reinterpreting text from the DOM as HTML can lead + * to a cross-site scripting vulnerability. + * @kind path-problem + * @scored + * @problem.severity error + * @security-severity 6.1 + * @id js/ml-powered/xss-through-dom + * @tags experimental security + * external/cwe/cwe-079 external/cwe/cwe-116 + */ + +import javascript +import ATM::ResultsInfo +import DataFlow::PathGraph +import experimental.adaptivethreatmodeling.XssThroughDomATM + +from AtmConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink, float score +where cfg.hasBoostedFlowPath(source, sink, score) +select sink.getNode(), source, sink, + "(Experimental) $@ may be reinterpreted as HTML without escaping meta-characters. Identified using machine learning.", + source.getNode(), "DOM text", score diff --git a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml index cab87ce0e33..58fe9d1197d 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml +++ b/javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml @@ -1,6 +1,7 @@ name: codeql/javascript-experimental-atm-queries +description: Experimental ML-powered queries for JavaScript language: javascript -version: 0.4.1 +version: 0.4.5 suites: codeql-suites defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls groups: diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.expected new file mode 100644 index 00000000000..f35770bad95 --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.expected @@ -0,0 +1,2 @@ +erroneousEndpoints +erroneousConfidences diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.ql b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.ql new file mode 100644 index 00000000000..9b06257b91f --- /dev/null +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.ql @@ -0,0 +1,90 @@ +/** + * ContradictoryEndpointCharacteristics.ql + * + * This tests surfaces endpoints that have a set of characteristics are logically incompatible with one another (e.g one + * high-confidence characteristic that implies a non-sink and another that implies a sink). If the test surfaces any + * such endpoints, this is a hint that some of our endpoint characteristics may be need to be adjusted. + */ + +import javascript +private import experimental.adaptivethreatmodeling.EndpointCharacteristics as EndpointCharacteristics +private import experimental.adaptivethreatmodeling.EndpointTypes as EndpointTypes + +/** + * Holds if `characteristic1` and `characteristic2` are among the several pairs of currently known high-confidence + * negative characteristics that apply to some known sinks. + * + * TODO: Experiment with lowering the confidence of `"FileSystemAccess"`, `"DOM"`, `"DatabaseAccess"`, and + * `"JQueryArgument"`. + */ +private predicate knownContradictoryCharacteristics( + EndpointCharacteristics::EndpointCharacteristic characteristic1, + EndpointCharacteristics::EndpointCharacteristic characteristic2 +) { + characteristic1 != characteristic2 and + ( + characteristic1 = ["TaintedPathSink", "FileSystemAccess"] and + characteristic2 = ["TaintedPathSink", "FileSystemAccess"] + or + characteristic1 = ["DomBasedXssSink", "DOM"] and + characteristic2 = ["DomBasedXssSink", "DOM"] + or + characteristic1 = ["DomBasedXssSink", "JQueryArgument"] and + characteristic2 = ["DomBasedXssSink", "JQueryArgument"] + or + characteristic1 = ["NosqlInjectionSink", "DatabaseAccess"] and + characteristic2 = ["NosqlInjectionSink", "DatabaseAccess"] + or + characteristic1 = ["SqlInjectionSink", "DatabaseAccess"] and + characteristic2 = ["SqlInjectionSink", "DatabaseAccess"] + ) +} + +/** + * Holds if the given endpoint has a self-contradictory combination of characteristics. Detects errors in our endpoint + * characteristics. Lists the problematic characterisitics and their implications for all such endpoints, together with + * an error message indicating why this combination is problematic. + */ +query predicate erroneousEndpoints( + DataFlow::Node endpoint, EndpointCharacteristics::EndpointCharacteristic characteristic, + EndpointTypes::EndpointType endpointClass, float confidence, string errorMessage +) { + // An endpoint's characteristics should not include positive indicators with medium/high confidence for more than one + // class. + exists( + EndpointCharacteristics::EndpointCharacteristic characteristic2, + EndpointTypes::EndpointType endpointClass2, float confidence2 + | + endpointClass.getEncoding() != endpointClass2.getEncoding() and + characteristic.appliesToEndpoint(endpoint) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointClass, true, confidence) and + characteristic2.hasImplications(endpointClass2, true, confidence2) and + confidence > characteristic.mediumConfidence() and + confidence2 > characteristic2.mediumConfidence() and + // We currently know of several high-confidence negative characteristics that apply to some known sinks. + not knownContradictoryCharacteristics(characteristic, characteristic2) + ) and + errorMessage = "Endpoint has high-confidence positive indicators for multiple classes" + or + // An enpoint's characteristics should not include positive indicators with medium/high confidence for some class and + // also include negative indicators with medium/high confidence for this same class. + exists(EndpointCharacteristics::EndpointCharacteristic characteristic2, float confidence2 | + characteristic.appliesToEndpoint(endpoint) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointClass, true, confidence) and + characteristic2.hasImplications(endpointClass, false, confidence2) and + confidence > characteristic.mediumConfidence() and + confidence2 > characteristic2.mediumConfidence() + ) and + errorMessage = "Endpoint has high-confidence positive and negative indicators for the same class" +} + +query predicate erroneousConfidences( + EndpointCharacteristics::EndpointCharacteristic characteristic, float confidence, + string errorMessage +) { + characteristic.hasImplications(_, _, confidence) and + (confidence < 0 or confidence > 1) and + errorMessage = "Characteristic has an indicator with confidence outside of [0, 1]" +} diff --git a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.expected b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.expected index 7fb7c716ce0..a8dbf544fdd 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.expected +++ b/javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/EndpointFeatures.expected @@ -156,26 +156,496 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/dbo.js:10:17:10:19 | err | enclosingFunctionBody | fn dbClient connect process env DB_URL err client db client db process env DB_NAME fn err | | autogenerated/NosqlAndSqlInjection/untyped/dbo.js:10:17:10:19 | err | enclosingFunctionName | connect | | autogenerated/NosqlAndSqlInjection/untyped/dbo.js:10:17:10:19 | err | fileImports | mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:1:23:1:31 | 'express' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:9:7:19 | '/post/:id' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:7:22:21:1 | functio ... `);\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | CalleeFlexibleAccessPath | kit.graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | calleeImports | @octokit/core | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | enclosingFunctionBody | req res id req params id response kit graphql \n query {\n repository(owner: "github", name: " id ") {\n object(expression: "master:foo") {\n ... on Blob {\n text\n }\n }\n }\n }\n | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:10:34:20:5 | `\\n ... }\\n ` | receiverName | kit | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:9:25:20 | '/user/:id/' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:25:23:34:1 | functio ... OT OK\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | CalleeFlexibleAccessPath | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | calleeImports | @octokit/graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | enclosingFunctionBody | req res id req params id response graphql foo id myGraphql withCustomRequest request response myGraphql foo id withDefaults graphql defaults withDefaults foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:27:30:27:40 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | CalleeFlexibleAccessPath | withCustomRequest | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | calleeImports | @octokit/graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | enclosingFunctionBody | req res id req params id response graphql foo id myGraphql withCustomRequest request response myGraphql foo id withDefaults graphql defaults withDefaults foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:29:41:29:47 | request | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | CalleeFlexibleAccessPath | myGraphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | calleeImports | @octokit/graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | enclosingFunctionBody | req res id req params id response graphql foo id myGraphql withCustomRequest request response myGraphql foo id withDefaults graphql defaults withDefaults foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:30:32:30:42 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | CalleeFlexibleAccessPath | graphql.defaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | calleeImports | @octokit/graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | enclosingFunctionBody | req res id req params id response graphql foo id myGraphql withCustomRequest request response myGraphql foo id withDefaults graphql defaults withDefaults foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:32:43:32:44 | {} | receiverName | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | CalleeFlexibleAccessPath | withDefaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | calleeImports | @octokit/graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | enclosingFunctionBody | req res id req params id response graphql foo id myGraphql withCustomRequest request response myGraphql foo id withDefaults graphql defaults withDefaults foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:33:18:33:28 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:36:29:36:46 | "@octokit/request" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:9:38:23 | '/article/:id/' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:38:26:49:1 | async f ... OT OK\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | CalleeFlexibleAccessPath | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:34:40:48 | "POST /graphql" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | CalleeFlexibleAccessPath | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:40:51:45:5 | {\\n ... K\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | CalleeFlexibleAccessPath | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | InputAccessPathFromCallee | 1.headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | assignedToPropName | headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:41:16:43:7 | {\\n ... } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | CalleeFlexibleAccessPath | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | InputAccessPathFromCallee | 1.headers.authorization | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | assignedToPropName | authorization | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:42:24:42:71 | "token ... 000001" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | CalleeFlexibleAccessPath | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | InputAccessPathFromCallee | 1.query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | assignedToPropName | query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:44:14:44:24 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | CalleeFlexibleAccessPath | request.defaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:47:43:47:44 | {} | receiverName | request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | CalleeFlexibleAccessPath | withDefaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:18:48:32 | "POST /graphql" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | CalleeFlexibleAccessPath | withDefaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:35:48:56 | { query ... {id}` } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | CalleeFlexibleAccessPath | withDefaults | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | InputAccessPathFromCallee | 1.query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | assignedToPropName | query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | calleeImports | @octokit/request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | enclosingFunctionBody | req res id req params id result request POST /graphql headers authorization token 0000000000000000000000000000000000000001 query foo id withDefaults request defaults withDefaults POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:48:44:48:54 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:9:54:21 | '/event/:id/' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:54:24:59:1 | async f ... OT OK\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | CalleeFlexibleAccessPath | kit2.graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | calleeImports | @octokit/rest | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | enclosingFunctionBody | req res id req params id result kit2 graphql foo id result2 kit2 request POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:56:39:56:49 | `foo ${id}` | receiverName | kit2 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | CalleeFlexibleAccessPath | kit2.request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | calleeImports | @octokit/rest | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | enclosingFunctionBody | req res id req params id result kit2 graphql foo id result2 kit2 request POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:40:58:54 | "POST /graphql" | receiverName | kit2 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | CalleeFlexibleAccessPath | kit2.request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | calleeImports | @octokit/rest | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | enclosingFunctionBody | req res id req params id result kit2 graphql foo id result2 kit2 request POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:57:58:78 | { query ... {id}` } | receiverName | kit2 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | CalleeFlexibleAccessPath | kit2.request | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | InputAccessPathFromCallee | 1.query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | assignedToPropName | query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | calleeImports | @octokit/rest | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | enclosingFunctionBody | req res id req params id result kit2 graphql foo id result2 kit2 request POST /graphql query foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:58:66:58:76 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | CalleeFlexibleAccessPath | buildSchema | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | calleeImports | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:62:26:66:1 | `\\n typ ... g\\n }\\n` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:9:73:20 | '/thing/:id' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:73:23:113:1 | async f ... \\n })\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | CalleeFlexibleAccessPath | nativeGraphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | calleeImports | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:38:75:43 | schema | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | CalleeFlexibleAccessPath | nativeGraphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | calleeImports | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:46:75:64 | "{ foo" + id + " }" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | CalleeFlexibleAccessPath | nativeGraphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | calleeImports | graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:75:67:75:70 | root | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:9:77:47 | "https: ... raphql" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:77:50:92:3 | {\\n m ... })\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | InputAccessPathFromCallee | 1.method | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | assignedToPropName | method | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:78:13:78:18 | "POST" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | InputAccessPathFromCallee | 1.headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | assignedToPropName | headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:79:14:81:5 | {\\n ... "\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | InputAccessPathFromCallee | 1.headers.Content-Type | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | assignedToPropName | Content-Type | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:80:23:80:40 | "application/json" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | InputAccessPathFromCallee | 1.body | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | assignedToPropName | body | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:26:91:5 | {\\n ... `\\n } | receiverName | JSON | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | InputAccessPathFromCallee | 0.query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | assignedToPropName | query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:84:14:90:8 | `{\\n ... }` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:9:94:47 | "https: ... raphql" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:94:50:112:3 | {\\n m ... })\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | InputAccessPathFromCallee | 1.method | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | assignedToPropName | method | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:95:13:95:18 | "POST" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | InputAccessPathFromCallee | 1.headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | assignedToPropName | headers | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:96:14:98:5 | {\\n ... "\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | InputAccessPathFromCallee | 1.headers.Content-Type | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | assignedToPropName | Content-Type | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:97:23:97:40 | "application/json" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | CalleeFlexibleAccessPath | fetch | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | InputAccessPathFromCallee | 1.body | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | assignedToPropName | body | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:26:111:5 | {\\n ... }\\n } | receiverName | JSON | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | InputAccessPathFromCallee | 0.query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | assignedToPropName | query | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:101:14:107:8 | `{\\n ... }` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | InputAccessPathFromCallee | 0.variables | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | assignedToPropName | variables | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:108:18:110:7 | {\\n ... } | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | CalleeFlexibleAccessPath | JSON.stringify | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | InputAccessPathFromCallee | 0.variables.id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | assignedToPropName | id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | enclosingFunctionBody | req res id req query id result nativeGraphql schema { foo id } root fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n id \n }\n } fetch https://my-grpahql-server.com/graphql method POST headers Content-Type application/json body JSON stringify query {\n thing {\n name\n url\n $id\n }\n } variables id id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:115:24:115:40 | '@actions/github' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:9:116:21 | '/event/:id/' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:116:24:121:1 | async f ... OT OK\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | CalleeFlexibleAccessPath | github.getOctokit | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | calleeImports | @actions/github | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | enclosingFunctionBody | req res kit github getOctokit foo id req params id result kit graphql foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:117:35:117:39 | "foo" | receiverName | github | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | CalleeFlexibleAccessPath | kit.graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | calleeImports | @actions/github | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | contextFunctionInterfaces | hello() | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | enclosingFunctionBody | req res kit github getOctokit foo id req params id result kit graphql foo id | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | enclosingFunctionName | app.get#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | fileImports | @actions/github @octokit/core @octokit/graphql @octokit/request @octokit/rest express graphql | +| autogenerated/NosqlAndSqlInjection/untyped/graphql.js:120:38:120:48 | `foo ${id}` | receiverName | kit | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | CalleeFlexibleAccessPath | ajv.compile | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | calleeImports | ajv | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | contextSurroundingFunctionParameters | | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:15:33:15:38 | schema | receiverName | ajv | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | CalleeFlexibleAccessPath | app.post | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | calleeImports | express | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | contextSurroundingFunctionParameters | | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:10:21:26 | '/documents/find' | receiverName | app | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | CalleeFlexibleAccessPath | app.post | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | InputArgumentIndex | 1 | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | calleeImports | express | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:21:29:37:1 | (req, r ... });\\n} | receiverName | app | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | CalleeFlexibleAccessPath | MongoClient.connect | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | InputArgumentIndex | 0 | @@ -184,7 +654,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:25:22:56 | 'mongod ... 7/test' | receiverName | MongoClient | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | CalleeFlexibleAccessPath | MongoClient.connect | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | InputArgumentIndex | 1 | @@ -193,7 +663,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:22:59:36:5 | (err, d ... K\\n } | receiverName | MongoClient | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | CalleeFlexibleAccessPath | db.collection | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | InputArgumentIndex | 0 | @@ -201,20 +671,20 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:23:33:23:37 | 'doc' | receiverName | db | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | CalleeFlexibleAccessPath | JSON.parse | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:34:25:47 | req.query.data | receiverName | JSON | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | CalleeFlexibleAccessPath | checkSchema | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | InputArgumentIndex | 0 | @@ -223,14 +693,14 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | CalleeFlexibleAccessPath | doc.find | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | contextFunctionInterfaces | validate(x) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:27:22:27:26 | query | receiverName | doc | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | CalleeFlexibleAccessPath | doc.find | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | InputArgumentIndex | 0 | @@ -238,7 +708,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:30:22:30:26 | query | receiverName | doc | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | CalleeFlexibleAccessPath | doc.find | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | InputArgumentIndex | 0 | @@ -246,7 +716,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:33:22:33:26 | query | receiverName | doc | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | CalleeFlexibleAccessPath | doc.find | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | InputArgumentIndex | 0 | @@ -254,8 +724,488 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data checkSchema query doc find query ajv validate schema query doc find query validate query doc find query doc find query | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | enclosingFunctionName | app.post#functionalargument | -| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | fileImports | ajv express mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | fileImports | ajv express joi mongodb | | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:35:18:35:22 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | CalleeFlexibleAccessPath | Joi.object | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | calleeImports | joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:41:30:44:1 | {\\n d ... red()\\n} | receiverName | Joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | CalleeFlexibleAccessPath | Joi.object | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | InputAccessPathFromCallee | 0.date | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | assignedToPropName | date | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | calleeImports | joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:42:11:42:33 | Joi.str ... uired() | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | CalleeFlexibleAccessPath | Joi.object | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | InputAccessPathFromCallee | 0.title | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | assignedToPropName | title | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | calleeImports | joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:43:12:43:34 | Joi.str ... uired() | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | CalleeFlexibleAccessPath | Joi.object().with | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | calleeImports | joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:9:44:14 | 'date' | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | CalleeFlexibleAccessPath | Joi.object().with | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | calleeImports | joi | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:44:17:44:23 | 'title' | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | CalleeFlexibleAccessPath | app.post | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:10:46:28 | '/documents/insert' | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | CalleeFlexibleAccessPath | app.post | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:46:31:64:1 | (req, r ... });\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | CalleeFlexibleAccessPath | MongoClient.connect | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | calleeImports | mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:25:47:56 | 'mongod ... 7/test' | receiverName | MongoClient | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | CalleeFlexibleAccessPath | MongoClient.connect | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | calleeImports | mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:47:59:63:5 | async ( ... }\\n } | receiverName | MongoClient | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | CalleeFlexibleAccessPath | db.collection | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:48:33:48:37 | 'doc' | receiverName | db | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | CalleeFlexibleAccessPath | JSON.parse | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:34:50:47 | req.query.data | receiverName | JSON | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | CalleeFlexibleAccessPath | doc.find | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:53:22:53:26 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | CalleeFlexibleAccessPath | doc.find | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:55:22:55:26 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | CalleeFlexibleAccessPath | doc.find | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:59:22:59:26 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | CalleeFlexibleAccessPath | doc.find | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | contextFunctionInterfaces | validate(x) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | contextSurroundingFunctionParameters | (req, res)\n(err, db) | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | enclosingFunctionBody | req res MongoClient connect mongodb://localhost:27017/test err db doc db collection doc query JSON parse req query data validate joiSchema validate query validate error doc find query doc find query joiSchema validateAsync query doc find query e doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | fileImports | ajv express joi mongodb | +| autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:61:22:61:26 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:1:22:1:27 | "http" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:2:21:2:25 | "url" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:3:22:3:29 | "ldapjs" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | CalleeFlexibleAccessPath | ldap.createClient | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:4:34:6:1 | {\\n url ... 389",\\n} | receiverName | ldap | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | CalleeFlexibleAccessPath | ldap.createClient | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | InputAccessPathFromCallee | 0.url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | assignedToPropName | url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:5:8:5:30 | "ldap:/ ... 1:1389" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | CalleeFlexibleAccessPath | input.replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:14:11:18 | /\\*/g | receiverName | input | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | CalleeFlexibleAccessPath | input.replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:11:21:11:26 | "\\\\2a" | receiverName | input | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | CalleeFlexibleAccessPath | input.replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:14:12:18 | /\\(/g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | CalleeFlexibleAccessPath | input.replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:12:21:12:26 | "\\\\28" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | CalleeFlexibleAccessPath | input.replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:14:13:18 | /\\)/g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | CalleeFlexibleAccessPath | input.replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:13:21:13:26 | "\\\\29" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | CalleeFlexibleAccessPath | input.replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:14:14:18 | /\\\\/g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | CalleeFlexibleAccessPath | input.replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:14:21:14:26 | "\\\\5c" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | CalleeFlexibleAccessPath | input.replace().replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:14:15:18 | /\\0/g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | CalleeFlexibleAccessPath | input.replace().replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:15:21:15:26 | "\\\\00" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | CalleeFlexibleAccessPath | input.replace().replace().replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:14:16:18 | /\\//g | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | CalleeFlexibleAccessPath | input.replace().replace().replace().replace().replace().replace | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | contextSurroundingFunctionParameters | (input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | enclosingFunctionBody | input input replace /\\*/g \\2a replace /\\(/g \\28 replace /\\)/g \\29 replace /\\\\/g \\5c replace /\\0/g \\00 replace /\\//g \\2f | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | enclosingFunctionName | sanitizeInput | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:16:21:16:26 | "\\\\2f" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | calleeImports | http | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:19:34:69:1 | (req, r ... OT OK\\n} | receiverName | http | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | CalleeFlexibleAccessPath | url.parse | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | calleeImports | url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:21:20:27 | req.url | receiverName | url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | CalleeFlexibleAccessPath | url.parse | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | calleeImports | url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:20:30:20:33 | true | receiverName | url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:17:28:27 | "o=example" | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:30:28:34 | opts1 | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:28:37:28:58 | functio ... res) {} | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:31:5:31:15 | "o=example" | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:5:32:61 | { filte ... e}))` } | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | InputAccessPathFromCallee | 1.filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | assignedToPropName | filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:33:5:33:26 | functio ... res) {} | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:38:5:38:15 | "o=example" | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:39:5:43:5 | { // OK ... ,\\n } | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | InputAccessPathFromCallee | 1.filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | assignedToPropName | filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:44:5:44:26 | functio ... res) {} | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:17:61:27 | "o=example" | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:30:61:42 | { filter: f } | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | InputAccessPathFromCallee | 1.filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | assignedToPropName | filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:40:61:40 | f | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:61:45:61:66 | functio ... res) {} | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | CalleeFlexibleAccessPath | ldap.parseFilter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | receiverName | ldap | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:17:66:27 | "o=example" | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:30:66:53 | { filte ... ilter } | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | InputAccessPathFromCallee | 1.filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | assignedToPropName | filter | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:40:66:51 | parsedFilter | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | CalleeFlexibleAccessPath | client.search | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | InputArgumentIndex | 2 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:66:56:66:77 | functio ... res) {} | receiverName | client | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | CalleeFlexibleAccessPath | ldap.parseDN | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:27:68:42 | `cn=${username}` | receiverName | ldap | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | CalleeFlexibleAccessPath | ldap.parseDN | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | calleeImports | ldapjs | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | contextSurroundingFunctionParameters | (req, res)\n(err, dn) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | enclosingFunctionBody | req res q url parse req url true username q query username opts1 filter (\|(name= username )(username= username )) client search o=example opts1 err res client search o=example filter (\|(name= username )(username= username )) err res client search o=example filter (\|(name= sanitizeInput username )(username= sanitizeInput username )) err res f OrFilter filters EqualityFilter attribute name value username EqualityFilter attribute username value username client search o=example filter f err res parsedFilter ldap parseFilter (\|(name= username )(username= username )) client search o=example filter parsedFilter err res dn ldap parseDN cn= username err dn | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:68:45:68:65 | functio ... dn) {} | receiverName | ldap | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | CalleeFlexibleAccessPath | server.listen | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | calleeImports | http | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:15:71:17 | 389 | receiverName | server | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | CalleeFlexibleAccessPath | server.listen | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | calleeImports | http | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | contextFunctionInterfaces | sanitizeInput(input) | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | contextSurroundingFunctionParameters | () | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | fileImports | http ldapjs url | +| autogenerated/NosqlAndSqlInjection/untyped/ldap.js:71:20:71:27 | () => {} | receiverName | server | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-from.js:1:24:1:31 | "marsdb" | CalleeFlexibleAccessPath | require | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-from.js:1:24:1:31 | "marsdb" | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-from.js:1:24:1:31 | "marsdb" | calleeImports | | @@ -309,16 +1259,16 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:10:9:26 | "/documents/find" | contextSurroundingFunctionParameters | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:10:9:26 | "/documents/find" | fileImports | ./marsdb-flow-from body-parser express | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:10:9:26 | "/documents/find" | receiverName | app | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | CalleeFlexibleAccessPath | app.post | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | InputArgumentIndex | 1 | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | calleeImports | express | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | contextFunctionInterfaces | | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | fileImports | ./marsdb-flow-from body-parser express | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... ery);\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | CalleeFlexibleAccessPath | app.post | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | contextFunctionInterfaces | | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | fileImports | ./marsdb-flow-from body-parser express | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:9:29:15:1 | (req, r ... {});\\n} | receiverName | app | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | contextFunctionInterfaces | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | enclosingFunctionBody | req res query query title req body title db myDoc find query | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | enclosingFunctionBody | req res query query title req body title db myDoc find query err data | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | enclosingFunctionName | app.post#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} | fileImports | ./marsdb-flow-from body-parser express | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | CalleeFlexibleAccessPath | db.myDoc.find | @@ -326,9 +1276,17 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | calleeImports | ./marsdb-flow-from | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | contextFunctionInterfaces | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | enclosingFunctionBody | req res query query title req body title db myDoc find query | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | enclosingFunctionBody | req res query query title req body title db myDoc find query err data | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | enclosingFunctionName | app.post#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:17:14:21 | query | fileImports | ./marsdb-flow-from body-parser express | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | CalleeFlexibleAccessPath | db.myDoc.find | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | calleeImports | ./marsdb-flow-from | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | contextFunctionInterfaces | | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | contextSurroundingFunctionParameters | (req, res)\n(err, data) | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | enclosingFunctionBody | req res query query title req body title db myDoc find query err data | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:14:24:14:40 | (err, data) => {} | fileImports | ./marsdb-flow-from body-parser express | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:1:25:1:33 | "express" | CalleeFlexibleAccessPath | require | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:1:25:1:33 | "express" | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:1:25:1:33 | "express" | calleeImports | | @@ -376,16 +1334,16 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:10:11:26 | "/documents/find" | contextSurroundingFunctionParameters | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:10:11:26 | "/documents/find" | fileImports | body-parser express marsdb | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:10:11:26 | "/documents/find" | receiverName | app | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | CalleeFlexibleAccessPath | app.post | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | InputArgumentIndex | 1 | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | calleeImports | express | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | contextFunctionInterfaces | | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | fileImports | body-parser express marsdb | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... ery);\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | CalleeFlexibleAccessPath | app.post | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | contextFunctionInterfaces | | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | fileImports | body-parser express marsdb | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:11:29:17:1 | (req, r ... {});\\n} | receiverName | app | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | contextFunctionInterfaces | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | enclosingFunctionBody | req res query query title req body title doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | enclosingFunctionBody | req res query query title req body title doc find query err data | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | enclosingFunctionName | app.post#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} | fileImports | body-parser express marsdb | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | CalleeFlexibleAccessPath | doc.find | @@ -393,10 +1351,19 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | calleeImports | marsdb | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | contextFunctionInterfaces | | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | enclosingFunctionBody | req res query query title req body title doc find query | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | enclosingFunctionBody | req res query query title req body title doc find query err data | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | enclosingFunctionName | app.post#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | fileImports | body-parser express marsdb | | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:12:16:16 | query | receiverName | doc | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | CalleeFlexibleAccessPath | doc.find | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | calleeImports | marsdb | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | contextFunctionInterfaces | | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | contextSurroundingFunctionParameters | (req, res)\n(err, data) | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | enclosingFunctionBody | req res query query title req body title doc find query err data | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | enclosingFunctionName | app.post#functionalargument | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | fileImports | body-parser express marsdb | +| autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:16:19:16:35 | (err, data) => {} | receiverName | doc | | autogenerated/NosqlAndSqlInjection/untyped/minimongo.js:1:25:1:33 | "express" | CalleeFlexibleAccessPath | require | | autogenerated/NosqlAndSqlInjection/untyped/minimongo.js:1:25:1:33 | "express" | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/minimongo.js:1:25:1:33 | "express" | calleeImports | | @@ -2327,6 +3294,146 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | enclosingFunctionBody | req res v JSON parse req body x MyModel find id v MyModel find id req body id MyModel find id req body id | | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | enclosingFunctionName | app.post#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` | fileImports | ./mongooseModel body-parser express | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:1:21:1:29 | "express" | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | CalleeFlexibleAccessPath | require | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | calleeImports | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:2:23:2:29 | 'mysql' | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | CalleeFlexibleAccessPath | mysql.createPool | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | calleeImports | mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:3:31:3:41 | getConfig() | receiverName | mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | contextSurroundingFunctionParameters | | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:9:5:16 | "search" | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | calleeImports | express | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:5:19:22:1 | functio ... });\\n} | receiverName | app | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | CalleeFlexibleAccessPath | pool.getConnection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | calleeImports | mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:7:24:12:5 | functio ... ;\\n } | receiverName | pool | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:8:26:11:9 | {\\n ... } | receiverName | connection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | InputAccessPathFromCallee | 0.sql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | assignedToPropName | sql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:9:18:9:59 | 'SELECT ... r` = ?' | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | InputAccessPathFromCallee | 0.values | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | assignedToPropName | values | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | contextSurroundingFunctionParameters | (req, res)\n(err, connection)\n(error, results, fields) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:11:12:11:46 | functio ... lds) {} | receiverName | connection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | CalleeFlexibleAccessPath | pool.getConnection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | calleeImports | mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:13:24:17:5 | functio ... ;\\n } | receiverName | pool | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:14:26:16:9 | {\\n ... } | receiverName | connection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | InputAccessPathFromCallee | 0.sql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | assignedToPropName | sql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:15:18:15:65 | 'SELECT ... + temp | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | contextSurroundingFunctionParameters | (req, res)\n(err, connection)\n(error, results, fields) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:16:12:16:46 | functio ... lds) {} | receiverName | connection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | CalleeFlexibleAccessPath | pool.getConnection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | calleeImports | mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:18:24:21:5 | functio ... ;\\n } | receiverName | pool | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | InputArgumentIndex | 0 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | contextSurroundingFunctionParameters | (req, res)\n(err, connection) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:19:26:19:73 | 'SELECT ... + temp | receiverName | connection | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | CalleeFlexibleAccessPath | connection.query | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | InputArgumentIndex | 1 | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | contextFunctionInterfaces | handler(req, res) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | contextSurroundingFunctionParameters | (req, res)\n(err, connection)\n(error, results, fields) | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | enclosingFunctionBody | req res temp req params value pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = ? values temp error results fields pool getConnection err connection connection query sql SELECT * FROM `books` WHERE `author` = temp error results fields pool getConnection err connection connection query SELECT * FROM `books` WHERE `author` = temp error results fields | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | enclosingFunctionName | handler | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | fileImports | express mysql | +| autogenerated/NosqlAndSqlInjection/untyped/mysql.js:20:13:20:47 | functio ... lds) {} | receiverName | connection | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise-types.ts:8:17:8:21 | taint | CalleeFlexibleAccessPath | this.db.one | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise-types.ts:8:17:8:21 | taint | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise-types.ts:8:17:8:21 | taint | contextFunctionInterfaces | constructor()\nonRequest(req, res) | @@ -2381,17 +3488,17 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:4:18:4:52 | process ... TRING'] | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | CalleeFlexibleAccessPath | db.any | @@ -2399,7 +3506,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:9:10:9:14 | query | receiverName | db | @@ -2408,7 +3515,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:10:11:10:15 | query | receiverName | db | @@ -2417,7 +3524,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:11:17:11:21 | query | receiverName | db | @@ -2426,7 +3533,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:12:10:12:14 | query | receiverName | db | @@ -2435,7 +3542,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:13:12:13:16 | query | receiverName | db | @@ -2444,7 +3551,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:14:18:14:22 | query | receiverName | db | @@ -2453,7 +3560,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:15:11:15:15 | query | receiverName | db | @@ -2462,7 +3569,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:16:10:16:14 | query | receiverName | db | @@ -2471,7 +3578,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:17:16:17:20 | query | receiverName | db | @@ -2480,7 +3587,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:18:12:18:16 | query | receiverName | db | @@ -2489,7 +3596,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:19:13:19:17 | query | receiverName | db | @@ -2498,7 +3605,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:21:10:23:3 | {\\n t ... OK\\n } | receiverName | db | @@ -2509,7 +3616,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:22:11:22:15 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | CalleeFlexibleAccessPath | db.one | @@ -2517,7 +3624,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:24:10:27:3 | {\\n t ... OK\\n } | receiverName | db | @@ -2528,7 +3635,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:25:11:25:44 | 'SELECT ... d = $1' | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | CalleeFlexibleAccessPath | db.one | @@ -2538,7 +3645,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | CalleeFlexibleAccessPath | db.one | @@ -2546,7 +3653,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:28:10:31:3 | {\\n t ... ter\\n } | receiverName | db | @@ -2557,7 +3664,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:29:11:29:48 | 'SELECT ... $1:raw' | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | CalleeFlexibleAccessPath | db.one | @@ -2567,7 +3674,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:30:13:30:25 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | CalleeFlexibleAccessPath | db.one | @@ -2575,7 +3682,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:32:10:35:3 | {\\n t ... OK\\n } | receiverName | db | @@ -2586,7 +3693,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:33:11:33:45 | 'SELECT ... = $1^' | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | CalleeFlexibleAccessPath | db.one | @@ -2596,7 +3703,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:34:13:34:25 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | CalleeFlexibleAccessPath | db.one | @@ -2604,7 +3711,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:36:10:43:3 | {\\n t ... ]\\n } | receiverName | db | @@ -2615,7 +3722,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:37:11:37:79 | 'SELECT ... o = $3' | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | CalleeFlexibleAccessPath | db.one | @@ -2625,22 +3732,22 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:39:7:39:19 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:40:7:40:21 | req.params.name | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | CalleeFlexibleAccessPath | db.one | @@ -2648,7 +3755,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:44:10:50:3 | {\\n t ... }\\n } | receiverName | db | @@ -2659,7 +3766,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:45:11:45:70 | 'SELECT ... {name}' | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | CalleeFlexibleAccessPath | db.one | @@ -2669,7 +3776,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:46:13:49:5 | {\\n ... n\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | CalleeFlexibleAccessPath | db.one | @@ -2679,7 +3786,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:47:11:47:23 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | CalleeFlexibleAccessPath | db.one | @@ -2689,7 +3796,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | CalleeFlexibleAccessPath | db.one | @@ -2697,7 +3804,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:51:10:58:3 | {\\n t ... }\\n } | receiverName | db | @@ -2708,7 +3815,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:52:11:52:121 | "SELECT ... lue%\\"" | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | CalleeFlexibleAccessPath | db.one | @@ -2718,7 +3825,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:53:13:57:5 | {\\n ... e\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | CalleeFlexibleAccessPath | db.one | @@ -2728,7 +3835,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:54:11:54:23 | req.params.id | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | CalleeFlexibleAccessPath | db.one | @@ -2738,7 +3845,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | CalleeFlexibleAccessPath | db.one | @@ -2748,7 +3855,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:56:14:56:29 | req.params.title | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | CalleeFlexibleAccessPath | db.task | @@ -2756,7 +3863,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:59:11:61:3 | t => {\\n ... OK\\n } | receiverName | db | @@ -2764,43 +3871,43 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:60:20:60:24 | query | receiverName | t | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | CalleeFlexibleAccessPath | db.task | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | CalleeFlexibleAccessPath | db.taskIf | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:5:63:30 | { cnd: ... uery) } | receiverName | db | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | CalleeFlexibleAccessPath | db.task | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | CalleeFlexibleAccessPath | db.taskIf | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | InputAccessPathFromCallee | 0.cnd | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | assignedToPropName | cnd | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:12:63:28 | t => t.one(query) | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | CalleeFlexibleAccessPath | t.one | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query | receiverName | t | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | CalleeFlexibleAccessPath | db.task | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | CalleeFlexibleAccessPath | db.taskIf | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | InputArgumentIndex | 1 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | calleeImports | pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:5:64:21 | t => t.one(query) | receiverName | db | @@ -2808,7 +3915,7 @@ tokenFeatures | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | InputArgumentIndex | 0 | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | contextFunctionInterfaces | cnd(t) | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | contextSurroundingFunctionParameters | (req, res)\n(t) | -| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db task cnd t t one query t t one query | +| autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | enclosingFunctionBody | req res db pgp process DB_CONNECTION_STRING env DB_CONNECTION_STRING query SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=' req params category ' ORDER BY PRICE db any query db many query db manyOrNone query db map query db multi query db multiResult query db none query db one query db oneOrNone query db query query db result query db one text query db one text SELECT * FROM news where id = $1 values req params id db one text SELECT * FROM news where id = $1:raw values req params id db one text SELECT * FROM news where id = $1^ values req params id db one text SELECT * FROM news where id = $1:raw AND name = $2:raw AND foo = $3 values req params id req params name req params foo db one text SELECT * FROM news where id = ${id}:raw AND name = ${name} values id req params id name req params name db one text SELECT * FROM news where id = ${id}:value AND name LIKE '%${name}:value%' AND title LIKE "%${title}:value%" values id req params id name req params name title req params title db task t t one query db taskIf cnd t t one query t t one query | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | enclosingFunctionName | get#functionalargument | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | fileImports | express pg-promise | | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:64:16:64:20 | query | receiverName | t | @@ -3542,37 +4649,37 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:1:18:1:21 | 'fs' | calleeImports | | | autogenerated/TaintedPath/TaintedPath.js:1:18:1:21 | 'fs' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:1:18:1:21 | 'fs' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:1:18:1:21 | 'fs' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:1:18:1:21 | 'fs' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | calleeImports | | | autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:2:20:2:25 | 'http' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | calleeImports | | | autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:3:19:3:23 | 'url' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | calleeImports | | | autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:4:24:4:42 | 'sanitize-filename' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | calleeImports | | | autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:5:26:5:31 | 'path' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:8:32:61:1 | functio ... h)));\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | InputArgumentIndex | 0 | @@ -3581,7 +4688,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:9:24:9:30 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | InputArgumentIndex | 1 | @@ -3590,7 +4697,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:9:33:9:36 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3598,7 +4705,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:12:13:12:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | InputArgumentIndex | 0 | @@ -3607,7 +4714,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:12:29:12:32 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | InputArgumentIndex | 0 | @@ -3615,7 +4722,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:15:13:15:49 | fs.read ... + path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | InputArgumentIndex | 0 | @@ -3624,7 +4731,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:15:29:15:48 | "/home/user/" + path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | InputArgumentIndex | 0 | @@ -3633,7 +4740,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:17:23:17:35 | "/home/user/" | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3641,7 +4748,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:18:17:18:37 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | InputArgumentIndex | 0 | @@ -3650,7 +4757,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:18:33:18:36 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | CalleeFlexibleAccessPath | path.indexOf | | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | InputArgumentIndex | 0 | @@ -3659,7 +4766,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:20:20:20:27 | "secret" | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3667,7 +4774,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:21:17:21:37 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | InputArgumentIndex | 0 | @@ -3676,7 +4783,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:21:33:21:36 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | CalleeFlexibleAccessPath | fs.existsSync | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | InputArgumentIndex | 0 | @@ -3685,7 +4792,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:23:21:23:24 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3693,7 +4800,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:24:17:24:37 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | InputArgumentIndex | 0 | @@ -3702,7 +4809,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:24:33:24:36 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3710,7 +4817,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:27:15:27:35 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | InputArgumentIndex | 0 | @@ -3719,7 +4826,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:27:31:27:34 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3727,7 +4834,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:30:15:30:35 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | InputArgumentIndex | 0 | @@ -3736,7 +4843,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:30:31:30:34 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -3744,7 +4851,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:33:15:33:35 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | InputArgumentIndex | 0 | @@ -3753,20 +4860,20 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:33:31:33:34 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:35:10:35:23 | sanitize(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:36:13:36:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | InputArgumentIndex | 0 | @@ -3775,7 +4882,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:36:29:36:32 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | InputArgumentIndex | 0 | @@ -3784,7 +4891,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:38:20:38:26 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | InputArgumentIndex | 1 | @@ -3793,7 +4900,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:38:29:38:32 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -3801,7 +4908,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:40:13:40:54 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | InputArgumentIndex | 0 | @@ -3810,7 +4917,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:40:29:40:53 | pathMod ... e(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | CalleeFlexibleAccessPath | pathModule.basename | | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | InputArgumentIndex | 0 | @@ -3819,7 +4926,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:40:49:40:52 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -3827,7 +4934,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:42:13:42:53 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | InputArgumentIndex | 0 | @@ -3836,7 +4943,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:42:29:42:52 | pathMod ... e(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | CalleeFlexibleAccessPath | pathModule.dirname | | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | InputArgumentIndex | 0 | @@ -3845,7 +4952,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:42:48:42:51 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -3853,7 +4960,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:44:13:44:53 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | InputArgumentIndex | 0 | @@ -3862,7 +4969,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:44:29:44:52 | pathMod ... e(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | CalleeFlexibleAccessPath | pathModule.extname | | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | InputArgumentIndex | 0 | @@ -3871,7 +4978,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:44:48:44:51 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -3879,7 +4986,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:46:13:46:50 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | InputArgumentIndex | 0 | @@ -3888,7 +4995,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:46:29:46:49 | pathMod ... n(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | InputArgumentIndex | 0 | @@ -3897,7 +5004,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:46:45:46:48 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | InputArgumentIndex | 0 | @@ -3905,7 +5012,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:13:48:59 | fs.read ... th, z)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | InputArgumentIndex | 0 | @@ -3914,7 +5021,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:29:48:58 | pathMod ... ath, z) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | InputArgumentIndex | 0 | @@ -3923,7 +5030,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:45:48:45 | x | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | InputArgumentIndex | 1 | @@ -3932,7 +5039,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:48:48:48 | y | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | InputArgumentIndex | 2 | @@ -3941,7 +5048,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:51:48:54 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | InputArgumentIndex | 3 | @@ -3950,7 +5057,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:48:57:48:57 | z | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -3958,7 +5065,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:50:13:50:55 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | InputArgumentIndex | 0 | @@ -3967,7 +5074,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:50:29:50:54 | pathMod ... e(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | InputArgumentIndex | 0 | @@ -3976,7 +5083,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:50:50:50:53 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | InputArgumentIndex | 0 | @@ -3984,7 +5091,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:52:13:52:57 | fs.read ... path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | InputArgumentIndex | 0 | @@ -3993,7 +5100,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:52:29:52:56 | pathMod ... , path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | InputArgumentIndex | 0 | @@ -4002,7 +5109,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:52:49:52:49 | x | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | InputArgumentIndex | 1 | @@ -4011,7 +5118,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:52:52:52:55 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | InputArgumentIndex | 0 | @@ -4019,7 +5126,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:54:13:54:57 | fs.read ... th, x)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | InputArgumentIndex | 0 | @@ -4028,7 +5135,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:54:29:54:56 | pathMod ... ath, x) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | InputArgumentIndex | 0 | @@ -4037,7 +5144,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:54:49:54:52 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | InputArgumentIndex | 1 | @@ -4046,7 +5153,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:54:55:54:55 | x | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -4054,7 +5161,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:56:13:56:53 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | InputArgumentIndex | 0 | @@ -4063,7 +5170,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:56:29:56:52 | pathMod ... e(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | InputArgumentIndex | 0 | @@ -4072,7 +5179,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:56:48:56:51 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | InputArgumentIndex | 0 | @@ -4080,7 +5187,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:13:58:62 | fs.read ... th, z)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | InputArgumentIndex | 0 | @@ -4089,7 +5196,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:29:58:61 | pathMod ... ath, z) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | InputArgumentIndex | 0 | @@ -4098,7 +5205,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:48:58:48 | x | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | InputArgumentIndex | 1 | @@ -4107,7 +5214,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:51:58:51 | y | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | InputArgumentIndex | 2 | @@ -4116,7 +5223,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:54:58:57 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | InputArgumentIndex | 3 | @@ -4125,7 +5232,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:58:60:58:60 | z | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -4133,7 +5240,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:60:13:60:62 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | InputArgumentIndex | 0 | @@ -4142,7 +5249,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:60:29:60:61 | pathMod ... h(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | CalleeFlexibleAccessPath | pathModule.toNamespacedPath | | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | InputArgumentIndex | 0 | @@ -4151,54 +5258,54 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path res write fs readFileSync /home/user/ path path startsWith /home/user/ res write fs readFileSync path path indexOf secret 1 res write fs readFileSync path fs existsSync path res write fs readFileSync path path foo.txt res write fs readFileSync path path foo.txt path bar.txt res write fs readFileSync path path foo.txt path bar.txt someOpaqueCondition res write fs readFileSync path path sanitize path res write fs readFileSync path path url parse req url true query path res write fs readFileSync pathModule basename path res write fs readFileSync pathModule dirname path res write fs readFileSync pathModule extname path res write fs readFileSync pathModule join path res write fs readFileSync pathModule join x y path z res write fs readFileSync pathModule normalize path res write fs readFileSync pathModule relative x path res write fs readFileSync pathModule relative path x res write fs readFileSync pathModule resolve path res write fs readFileSync pathModule resolve x y path z res write fs readFileSync pathModule toNamespacedPath path | | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:60:57:60:60 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | CalleeFlexibleAccessPath | angular.module | | autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:63:16:63:22 | 'myApp' | receiverName | angular | | autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | CalleeFlexibleAccessPath | angular.module | | autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:63:25:63:26 | [] | receiverName | angular | | autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | CalleeFlexibleAccessPath | angular.module().directive | | autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:64:16:64:27 | 'myCustomer' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | CalleeFlexibleAccessPath | angular.module().directive | | autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | contextSurroundingFunctionParameters | () | -| autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:64:30:68:5 | functio ... }\\n } | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | CalleeFlexibleAccessPath | angular.module().directive().directive | | autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:69:16:69:27 | 'myCustomer' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | CalleeFlexibleAccessPath | angular.module().directive().directive | | autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | contextSurroundingFunctionParameters | () | -| autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:69:30:73:5 | functio ... }\\n } | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | CalleeFlexibleAccessPath | Cookie.get | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | enclosingFunctionBody | templateUrl Cookie get unsafe | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | enclosingFunctionName | directive#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:71:37:71:44 | "unsafe" | receiverName | Cookie | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:75:32:80:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | InputArgumentIndex | 0 | @@ -4206,7 +5313,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:77:15:77:77 | fs.read ... .query) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | InputArgumentIndex | 0 | @@ -4215,7 +5322,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:77:31:77:76 | require ... ).query | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | InputArgumentIndex | 0 | @@ -4224,7 +5331,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:77:39:77:54 | "querystringify" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | CalleeFlexibleAccessPath | import(!).parse | | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | calleeImports | querystringify | @@ -4232,14 +5339,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:77:63:77:69 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:78:15:78:75 | fs.read ... .query) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | InputArgumentIndex | 0 | @@ -4248,7 +5355,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:78:31:78:74 | require ... ).query | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | InputArgumentIndex | 0 | @@ -4257,7 +5364,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:78:39:78:52 | "query-string" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | CalleeFlexibleAccessPath | import(!).parse | | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | calleeImports | query-string | @@ -4265,14 +5372,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:78:61:78:67 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:79:15:79:74 | fs.read ... .query) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | InputArgumentIndex | 0 | @@ -4281,7 +5388,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:79:31:79:73 | require ... ).query | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | InputArgumentIndex | 0 | @@ -4290,7 +5397,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:79:39:79:51 | "querystring" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | CalleeFlexibleAccessPath | import(!).parse | | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | calleeImports | querystring | @@ -4298,7 +5405,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | enclosingFunctionBody | req res res write fs readFileSync require querystringify parse req url query res write fs readFileSync require query-string parse req url query res write fs readFileSync require querystring parse req url query | | autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:79:60:79:66 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | calleeImports | | @@ -4306,14 +5413,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:84:27:84:35 | 'express' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | CalleeFlexibleAccessPath | res.render | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | contextSurroundingFunctionParameters | ()\n(req, res) | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:87:48:87:60 | req.params[0] | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | CalleeFlexibleAccessPath | application.get | | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | InputArgumentIndex | 0 | @@ -4322,7 +5429,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:88:21:88:30 | '/views/*' | receiverName | application | | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | CalleeFlexibleAccessPath | application.get | | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | InputArgumentIndex | 1 | @@ -4331,7 +5438,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:88:33:88:43 | views_local | receiverName | application | | autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | InputArgumentIndex | 0 | @@ -4340,7 +5447,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:90:34:90:42 | "./views" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | CalleeFlexibleAccessPath | application.get | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | calleeImports | express | @@ -4348,7 +5455,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:91:21:91:30 | '/views/*' | receiverName | application | | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | CalleeFlexibleAccessPath | application.get | | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | InputArgumentIndex | 1 | @@ -4357,25 +5464,25 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | contextSurroundingFunctionParameters | () | | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | enclosingFunctionBody | express require express application express views_local req res res render req 0 params 0 application get /views/* views_local views_imported require ./views application get /views/* views_imported | | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | enclosingFunctionName | | -| autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:91:33:91:46 | views_imported | receiverName | application | | autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | CalleeFlexibleAccessPath | addEventListener | | autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:95:18:95:26 | 'message' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | CalleeFlexibleAccessPath | addEventListener | | autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | contextSurroundingFunctionParameters | (ev) | -| autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:95:29:97:1 | (ev) => ... ata);\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | CalleeFlexibleAccessPath | Cookie.set | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | contextSurroundingFunctionParameters | (ev) | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | enclosingFunctionBody | ev Cookie set unsafe ev data | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | enclosingFunctionName | addEventListener#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:96:14:96:21 | "unsafe" | receiverName | Cookie | | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | CalleeFlexibleAccessPath | Cookie.set | | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | InputArgumentIndex | 1 | @@ -4383,14 +5490,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | contextSurroundingFunctionParameters | (ev) | | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | enclosingFunctionBody | ev Cookie set unsafe ev data | | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | enclosingFunctionName | addEventListener#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:96:24:96:30 | ev.data | receiverName | Cookie | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:99:32:109:1 | functio ... );\\n\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | InputArgumentIndex | 0 | @@ -4399,7 +5506,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:100:23:100:29 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | InputArgumentIndex | 1 | @@ -4408,7 +5515,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:100:32:100:35 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | InputArgumentIndex | 0 | @@ -4416,7 +5523,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:102:12:102:49 | fs.read ... (path)) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | InputArgumentIndex | 0 | @@ -4425,7 +5532,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:102:28:102:48 | fs.real ... c(path) | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | CalleeFlexibleAccessPath | fs.realpathSync | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | InputArgumentIndex | 0 | @@ -4434,7 +5541,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:102:44:102:47 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | CalleeFlexibleAccessPath | fs.realpath | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | InputArgumentIndex | 0 | @@ -4443,7 +5550,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:103:14:103:17 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | CalleeFlexibleAccessPath | fs.realpath | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | InputArgumentIndex | 1 | @@ -4452,7 +5559,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | contextSurroundingFunctionParameters | (req, res)\n(err, realpath) | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:104:18:106:18 | functio ... } | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | InputArgumentIndex | 0 | @@ -4460,7 +5567,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | contextSurroundingFunctionParameters | (req, res)\n(err, realpath) | | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:105:29:105:53 | fs.read ... alpath) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | InputArgumentIndex | 0 | @@ -4469,14 +5576,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | contextSurroundingFunctionParameters | (req, res)\n(err, realpath) | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync fs realpathSync path fs realpath path err realpath res write fs readFileSync realpath | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:105:45:105:52 | realpath | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:111:32:120:1 | functio ... bove.\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | InputArgumentIndex | 0 | @@ -4485,7 +5592,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:112:24:112:30 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | InputArgumentIndex | 1 | @@ -4494,13 +5601,13 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:112:33:112:36 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | calleeImports | url | @@ -4508,7 +5615,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:115:25:115:46 | /[\\]\\[* ... \\?\\/]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | InputArgumentIndex | 1 | @@ -4517,13 +5624,13 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:115:49:115:50 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | calleeImports | url | @@ -4531,7 +5638,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:116:25:116:31 | /\\.\\./g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | InputArgumentIndex | 1 | @@ -4540,7 +5647,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:116:34:116:35 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -4548,7 +5655,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:119:13:119:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | InputArgumentIndex | 0 | @@ -4557,14 +5664,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:119:29:119:32 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:122:32:133:1 | functio ... bove.\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | InputArgumentIndex | 0 | @@ -4573,7 +5680,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:123:24:123:30 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | InputArgumentIndex | 1 | @@ -4582,13 +5689,13 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:123:33:123:36 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | calleeImports | url | @@ -4596,7 +5703,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:128:24:128:45 | /[\\]\\[* ... \\?\\/]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | InputArgumentIndex | 1 | @@ -4605,13 +5712,13 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:128:48:128:49 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | calleeImports | url | @@ -4619,7 +5726,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:129:25:129:31 | /\\.\\./g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | InputArgumentIndex | 1 | @@ -4628,7 +5735,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:129:34:129:35 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -4636,7 +5743,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:132:13:132:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | InputArgumentIndex | 0 | @@ -4645,14 +5752,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | enclosingFunctionBody | req res path url parse req url true query path path path path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g path path replace /\\.\\./g res write fs readFileSync path | | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:132:29:132:32 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:135:32:139:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | InputArgumentIndex | 0 | @@ -4661,7 +5768,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | enclosingFunctionBody | req res path url parse req url true query path require send req path | | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:136:23:136:29 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | InputArgumentIndex | 1 | @@ -4670,7 +5777,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | enclosingFunctionBody | req res path url parse req url true query path require send req path | | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:136:32:136:35 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | InputArgumentIndex | 0 | @@ -4679,7 +5786,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | enclosingFunctionBody | req res path url parse req url true query path require send req path | | autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:138:10:138:15 | 'send' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | CalleeFlexibleAccessPath | import(!) | | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | calleeImports | send | @@ -4687,7 +5794,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | enclosingFunctionBody | req res path url parse req url true query path require send req path | | autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:138:18:138:20 | req | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | CalleeFlexibleAccessPath | import(!) | | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | calleeImports | send | @@ -4695,13 +5802,13 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | enclosingFunctionBody | req res path url parse req url true query path require send req path | | autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:138:23:138:26 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:141:32:163:1 | functio ... OK \\n\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | InputArgumentIndex | 0 | @@ -4710,7 +5817,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:142:24:142:30 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | InputArgumentIndex | 1 | @@ -4719,7 +5826,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:142:33:142:36 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | InputArgumentIndex | 0 | @@ -4728,7 +5835,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:144:19:144:22 | path | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | CalleeFlexibleAccessPath | path.split | | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | InputArgumentIndex | 0 | @@ -4737,7 +5844,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:146:26:146:28 | "/" | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | InputArgumentIndex | 0 | @@ -4746,7 +5853,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:148:19:148:33 | split.join("/") | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | CalleeFlexibleAccessPath | split.join | | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | InputArgumentIndex | 0 | @@ -4755,7 +5862,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:148:30:148:32 | "/" | receiverName | split | | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | InputArgumentIndex | 0 | @@ -4764,7 +5871,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:150:19:150:50 | prefix ... th - 1] | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | InputArgumentIndex | 0 | @@ -4773,7 +5880,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:152:19:152:26 | split[x] | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | InputArgumentIndex | 0 | @@ -4782,7 +5889,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:153:19:153:35 | prefix + split[x] | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | CalleeFlexibleAccessPath | prefix.concat | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | InputArgumentIndex | 0 | @@ -4790,7 +5897,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | receiverName | prefix | | autogenerated/TaintedPath/TaintedPath.js:155:33:155:37 | split | stringConcatenatedWith | prefix -endpoint- | | autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | CalleeFlexibleAccessPath | fs.readFileSync | @@ -4800,7 +5907,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:156:19:156:37 | concatted.join("/") | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | CalleeFlexibleAccessPath | concatted.join | | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | InputArgumentIndex | 0 | @@ -4808,7 +5915,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:156:34:156:36 | "/" | receiverName | concatted | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | CalleeFlexibleAccessPath | split.concat | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | InputArgumentIndex | 0 | @@ -4817,7 +5924,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | receiverName | split | | autogenerated/TaintedPath/TaintedPath.js:158:33:158:38 | prefix | stringConcatenatedWith | split -endpoint- | | autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | CalleeFlexibleAccessPath | fs.readFileSync | @@ -4827,7 +5934,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:159:19:159:38 | concatted2.join("/") | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | CalleeFlexibleAccessPath | concatted2.join | | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | InputArgumentIndex | 0 | @@ -4836,7 +5943,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:159:35:159:37 | "/" | receiverName | concatted2 | | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | InputArgumentIndex | 0 | @@ -4845,14 +5952,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path split path split / fs readFileSync split join / fs readFileSync prefix split split length 1 fs readFileSync split x fs readFileSync prefix split x concatted prefix concat split fs readFileSync concatted join / concatted2 split concat prefix fs readFileSync concatted2 join / fs readFileSync split pop | | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:161:19:161:29 | split.pop() | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | calleeImports | http | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:165:32:196:1 | functio ... lute)\\n} | receiverName | http | | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | InputArgumentIndex | 0 | @@ -4861,7 +5968,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:166:24:166:30 | req.url | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | InputArgumentIndex | 1 | @@ -4870,7 +5977,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:166:33:166:36 | true | receiverName | url | | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -4878,7 +5985,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:169:13:169:69 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -4887,7 +5994,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:169:29:169:68 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | InputArgumentIndex | 0 | @@ -4896,7 +6003,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:169:42:169:63 | /[\\]\\[* ... \\?\\/]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | InputArgumentIndex | 1 | @@ -4905,7 +6012,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:169:66:169:67 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -4913,7 +6020,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:170:13:170:56 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -4922,7 +6029,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:170:29:170:55 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | InputArgumentIndex | 0 | @@ -4931,7 +6038,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:170:42:170:50 | /[abcd]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | InputArgumentIndex | 1 | @@ -4940,7 +6047,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:170:53:170:54 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -4948,7 +6055,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:171:13:171:54 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -4957,7 +6064,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:171:29:171:53 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | InputArgumentIndex | 0 | @@ -4966,7 +6073,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:171:42:171:48 | /[./]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | InputArgumentIndex | 1 | @@ -4975,7 +6082,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:171:51:171:52 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -4983,7 +6090,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:172:13:172:65 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -4992,7 +6099,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:172:29:172:64 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | InputArgumentIndex | 0 | @@ -5001,7 +6108,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:172:42:172:59 | /[foobar/foobar]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | InputArgumentIndex | 1 | @@ -5010,7 +6117,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:172:62:172:63 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5018,7 +6125,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:173:13:173:52 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5027,7 +6134,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:173:29:173:51 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | InputArgumentIndex | 0 | @@ -5036,7 +6143,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:173:42:173:46 | /\\//g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | InputArgumentIndex | 1 | @@ -5045,7 +6152,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:173:49:173:50 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5053,7 +6160,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:174:13:174:55 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5062,7 +6169,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:174:29:174:54 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | InputArgumentIndex | 0 | @@ -5071,7 +6178,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:174:42:174:49 | /\\.\|\\//g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | InputArgumentIndex | 1 | @@ -5080,7 +6187,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:174:52:174:53 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5088,7 +6195,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:176:13:176:53 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5097,7 +6204,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:176:29:176:52 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | InputArgumentIndex | 0 | @@ -5106,7 +6213,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:176:42:176:47 | /[.]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | InputArgumentIndex | 1 | @@ -5115,7 +6222,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:176:50:176:51 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5123,7 +6230,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:177:13:177:54 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5132,7 +6239,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:177:29:177:53 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | InputArgumentIndex | 0 | @@ -5141,7 +6248,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:177:42:177:48 | /[..]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | InputArgumentIndex | 1 | @@ -5150,7 +6257,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:177:51:177:52 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5158,7 +6265,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:178:13:178:52 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5167,7 +6274,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:178:29:178:51 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | InputArgumentIndex | 0 | @@ -5176,7 +6283,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:178:42:178:46 | /\\./g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | InputArgumentIndex | 1 | @@ -5185,7 +6292,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:178:49:178:50 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5193,7 +6300,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:179:13:179:58 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5202,7 +6309,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:179:29:179:57 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | InputArgumentIndex | 0 | @@ -5211,7 +6318,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:179:42:179:52 | /\\.\\.\|BLA/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | InputArgumentIndex | 1 | @@ -5220,7 +6327,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:179:55:179:56 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5228,7 +6335,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:182:15:182:55 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5237,7 +6344,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:182:31:182:54 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | InputArgumentIndex | 0 | @@ -5246,7 +6353,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:182:44:182:49 | /[.]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | InputArgumentIndex | 1 | @@ -5255,7 +6362,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:182:52:182:53 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5263,7 +6370,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:183:14:183:55 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5272,7 +6379,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:183:30:183:54 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | InputArgumentIndex | 0 | @@ -5281,7 +6388,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:183:43:183:49 | /[..]/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | InputArgumentIndex | 1 | @@ -5290,7 +6397,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:183:52:183:53 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5298,7 +6405,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:184:15:184:54 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5307,7 +6414,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:184:31:184:53 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | InputArgumentIndex | 0 | @@ -5316,7 +6423,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:184:44:184:48 | /\\./g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | InputArgumentIndex | 1 | @@ -5325,7 +6432,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:184:51:184:52 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | InputArgumentIndex | 0 | @@ -5333,7 +6440,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:185:14:185:59 | fs.read ... g, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | InputArgumentIndex | 0 | @@ -5342,7 +6449,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:185:30:185:58 | path.re ... /g, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | InputArgumentIndex | 0 | @@ -5351,7 +6458,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:185:43:185:53 | /\\.\\.\|BLA/g | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | InputArgumentIndex | 1 | @@ -5360,7 +6467,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:185:56:185:57 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | InputArgumentIndex | 0 | @@ -5368,7 +6475,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:189:13:189:96 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | InputArgumentIndex | 0 | @@ -5377,7 +6484,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:189:29:189:95 | "prefix ... +/, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | InputArgumentIndex | 0 | @@ -5386,7 +6493,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:189:61:189:64 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | InputArgumentIndex | 0 | @@ -5395,7 +6502,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:189:75:189:90 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | calleeImports | path | @@ -5403,14 +6510,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:189:93:189:94 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:190:13:190:95 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | InputArgumentIndex | 0 | @@ -5419,7 +6526,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:190:29:190:94 | "prefix ... +/, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | InputArgumentIndex | 0 | @@ -5428,7 +6535,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:190:61:190:64 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | InputArgumentIndex | 0 | @@ -5437,7 +6544,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:190:75:190:89 | /(\\.\\.[\\/\\\\])+/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | calleeImports | path | @@ -5445,14 +6552,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:190:92:190:93 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:191:13:191:91 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | InputArgumentIndex | 0 | @@ -5461,7 +6568,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:191:29:191:90 | "prefix ... +/, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | InputArgumentIndex | 0 | @@ -5470,7 +6577,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:191:61:191:64 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | InputArgumentIndex | 0 | @@ -5479,7 +6586,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:191:75:191:85 | /(\\.\\.\\/)+/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | calleeImports | path | @@ -5487,14 +6594,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:191:88:191:89 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:192:13:192:91 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | InputArgumentIndex | 0 | @@ -5503,7 +6610,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:192:29:192:90 | "prefix ... */, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | InputArgumentIndex | 0 | @@ -5512,7 +6619,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:192:61:192:64 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | InputArgumentIndex | 0 | @@ -5521,7 +6628,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:192:75:192:85 | /(\\.\\.\\/)*/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | calleeImports | path | @@ -5529,14 +6636,14 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:192:88:192:89 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | InputArgumentIndex | 0 | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | contextFunctionInterfaces | views_local(req, res) | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:194:13:194:74 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | InputArgumentIndex | 0 | @@ -5545,7 +6652,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | InputArgumentIndex | 0 | @@ -5554,7 +6661,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:194:53:194:68 | /^(\\.\\.[\\/\\\\])+/ | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | InputArgumentIndex | 1 | @@ -5563,7 +6670,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:194:71:194:72 | '' | receiverName | path | | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | InputArgumentIndex | 0 | @@ -5571,7 +6678,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:195:13:195:85 | fs.read ... /, '')) | receiverName | res | | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | InputArgumentIndex | 0 | @@ -5580,7 +6687,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | receiverName | fs | | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | InputArgumentIndex | 0 | @@ -5589,7 +6696,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:195:50:195:53 | path | receiverName | pathModule | | autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | InputArgumentIndex | 0 | @@ -5598,7 +6705,7 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:195:64:195:79 | /^(\\.\\.[\\/\\\\])+/ | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | calleeImports | path | @@ -5606,7 +6713,639 @@ tokenFeatures | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | enclosingFunctionBody | req res path url parse req url true query path res write fs readFileSync path replace /[\\]\\[*,;'"`<>\\\\?\\/]/g res write fs readFileSync path replace /[abcd]/g res write fs readFileSync path replace /[./]/g res write fs readFileSync path replace /[foobar/foobar]/g res write fs readFileSync path replace /\\//g res write fs readFileSync path replace /\\.\|\\//g res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g pathModule isAbsolute path res write fs readFileSync path replace /[.]/g res write fs readFileSync path replace /[..]/g res write fs readFileSync path replace /\\./g res write fs readFileSync path replace /\\.\\.\|BLA/g res write fs readFileSync prefix pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.[\\/\\\\])+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)+/ res write fs readFileSync prefix pathModule normalize path replace /(\\.\\.\\/)*/ res write fs readFileSync prefix path replace /^(\\.\\.[\\/\\\\])+/ res write fs readFileSync pathModule normalize path replace /^(\\.\\.[\\/\\\\])+/ | | autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | fileImports | ./views express fs http path query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:195:82:195:83 | '' | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:200:32:207:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | calleeImports | | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:202:22:202:25 | "qs" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | CalleeFlexibleAccessPath | res.write | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:203:13:203:50 | fs.read ... l).foo) | receiverName | res | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | calleeImports | fs | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:203:29:203:49 | qs.pars ... rl).foo | receiverName | fs | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | CalleeFlexibleAccessPath | qs.parse | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | calleeImports | qs | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:203:38:203:44 | req.url | receiverName | qs | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | CalleeFlexibleAccessPath | res.write | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:204:13:204:64 | fs.read ... )).foo) | receiverName | res | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | calleeImports | fs | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:204:29:204:63 | qs.pars ... l)).foo | receiverName | fs | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | CalleeFlexibleAccessPath | qs.parse | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | calleeImports | qs | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:204:38:204:58 | normali ... eq.url) | receiverName | qs | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | CalleeFlexibleAccessPath | normalizeUrl | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | calleeImports | normalize-url | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:204:51:204:57 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | calleeImports | | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:205:27:205:35 | "parseqs" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | CalleeFlexibleAccessPath | res.write | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:206:13:206:56 | fs.read ... l).foo) | receiverName | res | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | calleeImports | fs | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:206:29:206:55 | parseqs ... rl).foo | receiverName | fs | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | CalleeFlexibleAccessPath | parseqs.decode | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | calleeImports | parseqs | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | enclosingFunctionBody | req res qs require qs res write fs readFileSync qs parse req url foo res write fs readFileSync qs parse normalizeUrl req url foo parseqs require parseqs res write fs readFileSync parseqs decode req url foo | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:206:44:206:50 | req.url | receiverName | parseqs | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | calleeImports | | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/TaintedPath.js:209:20:209:34 | "child_process" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:210:32:215:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | calleeImports | url | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:211:24:211:30 | req.url | receiverName | url | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | calleeImports | url | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:211:33:211:36 | true | receiverName | url | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | CalleeFlexibleAccessPath | cp.execSync | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:212:15:212:22 | "foobar" | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | CalleeFlexibleAccessPath | cp.execSync | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:212:25:212:35 | {cwd: path} | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | CalleeFlexibleAccessPath | cp.execSync | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | InputAccessPathFromCallee | 1.cwd | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | assignedToPropName | cwd | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:212:31:212:34 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:213:19:213:26 | "foobar" | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:213:29:213:36 | ["args"] | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:213:30:213:35 | "args" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:30:213:35 | "args" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:30:213:35 | "args" | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:213:30:213:35 | "args" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:213:30:213:35 | "args" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | InputArgumentIndex | 2 | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:213:39:213:49 | {cwd: path} | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | InputAccessPathFromCallee | 2.cwd | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | InputArgumentIndex | 2 | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | assignedToPropName | cwd | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:213:45:213:48 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:214:19:214:26 | "foobar" | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/TaintedPath.js:214:29:214:39 | {cwd: path} | receiverName | cp | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | CalleeFlexibleAccessPath | cp.execFileSync | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | InputAccessPathFromCallee | 1.cwd | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | assignedToPropName | cwd | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | calleeImports | child_process | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | contextFunctionInterfaces | views_local(req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | enclosingFunctionBody | req res path url parse req url true query path cp execSync foobar cwd path cp execFileSync foobar args cwd path cp execFileSync foobar cwd path | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/TaintedPath.js:214:35:214:38 | path | fileImports | ./views child_process express fs http normalize-url parseqs path qs query-string querystring querystringify sanitize-filename send url | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | calleeImports | | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/express.js:1:23:1:31 | "express" | fileImports | express express-fileupload | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | calleeImports | | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/express.js:2:24:2:43 | "express-fileupload" | fileImports | express express-fileupload | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | CalleeFlexibleAccessPath | app.use | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | calleeImports | express | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | fileImports | express express-fileupload | +| autogenerated/TaintedPath/express.js:5:9:5:20 | fileUpload() | receiverName | app | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | calleeImports | express | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | fileImports | express express-fileupload | +| autogenerated/TaintedPath/express.js:7:9:7:20 | "/some/path" | receiverName | app | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | calleeImports | express | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | fileImports | express express-fileupload | +| autogenerated/TaintedPath/express.js:7:23:9:1 | functio ... bar);\\n} | receiverName | app | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | CalleeFlexibleAccessPath | req.files.foo.mv | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | contextFunctionInterfaces | | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | enclosingFunctionBody | req res req files foo mv req query bar | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/express.js:8:20:8:32 | req.query.bar | fileImports | express express-fileupload | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | calleeImports | | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:1:25:1:33 | 'express' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | calleeImports | | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:2:20:2:31 | "handlebars" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | calleeImports | | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:3:20:3:23 | "fs" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | CalleeFlexibleAccessPath | hb.registerHelper | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:10:23:10:31 | "catFile" | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | CalleeFlexibleAccessPath | hb.registerHelper | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | contextSurroundingFunctionParameters | ()\n(filePath) | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:10:34:12:5 | functio ... )\\n } | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | contextSurroundingFunctionParameters | ()\n(filePath) | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:11:32:11:39 | filePath | receiverName | fs | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | CalleeFlexibleAccessPath | hb.registerHelper | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:13:23:13:38 | "prependToLines" | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | CalleeFlexibleAccessPath | hb.registerHelper | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | contextSurroundingFunctionParameters | ()\n(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:13:41:19:5 | functio ... ;\\n } | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | contextSurroundingFunctionParameters | ()\n(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:15:25:15:32 | filePath | receiverName | fs | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | CalleeFlexibleAccessPath | fs.readFileSync().split | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | contextSurroundingFunctionParameters | ()\n(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:16:18:16:21 | "\\n" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | CalleeFlexibleAccessPath | fs.readFileSync().split().map | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | contextSurroundingFunctionParameters | ()\n(prefix, filePath)\n(line) | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:17:16:17:38 | (line) ... + line | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | CalleeFlexibleAccessPath | fs.readFileSync().split().map().join | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | contextSurroundingFunctionParameters | ()\n(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:18:17:18:20 | "\\n" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | CalleeFlexibleAccessPath | hb.compile | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:20:42:20:90 | "conten ... path}}" | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | CalleeFlexibleAccessPath | hb.compile | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:21:38:21:54 | "hello, {{name}}" | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | CalleeFlexibleAccessPath | hb.compile | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:22:39:22:74 | fs.read ... plate") | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | calleeImports | fs | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:22:55:22:73 | "greeting.template" | receiverName | fs | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | CalleeFlexibleAccessPath | hb.compile | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | calleeImports | handlebars | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | contextSurroundingFunctionParameters | () | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | enclosingFunctionBody | hb registerHelper catFile catFile filePath fs readFileSync filePath hb registerHelper prependToLines prependToLines prefix filePath fs readFileSync filePath split \n map line prefix line join \n data compiledFileAccess hb compile contents of file {{path}} are: {{catFile path}} data compiledBenign hb compile hello, {{name}} data compiledUnknown hb compile fs readFileSync greeting.template data compiledMixed hb compile helpers may have several args, like here: {{prependToLines prefix path}} | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | enclosingFunctionName | init | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:23:37:23:110 | "helper ... path}}" | receiverName | hb | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:28:9:28:21 | '/some/path1' | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:28:24:30:1 | functio ... File)\\n} | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | CalleeFlexibleAccessPath | res.send | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | enclosingFunctionBody | req res res send data compiledFileAccess path req params path | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:29:14:29:63 | data.co ... path }) | receiverName | res | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | CalleeFlexibleAccessPath | data.compiledFileAccess | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | enclosingFunctionBody | req res res send data compiledFileAccess path req params path | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } | receiverName | data | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | CalleeFlexibleAccessPath | data.compiledFileAccess | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | InputAccessPathFromCallee | 0.path | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | assignedToPropName | path | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | enclosingFunctionBody | req res res send data compiledFileAccess path req params path | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:32:9:32:21 | '/some/path2' | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:32:24:34:1 | functio ... File)\\n} | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | CalleeFlexibleAccessPath | res.send | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | enclosingFunctionBody | req res res send data compiledBenign name req params name | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:33:14:33:59 | data.co ... name }) | receiverName | res | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | CalleeFlexibleAccessPath | data.compiledBenign | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | enclosingFunctionBody | req res res send data compiledBenign name req params name | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } | receiverName | data | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | CalleeFlexibleAccessPath | data.compiledBenign | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | InputAccessPathFromCallee | 0.name | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | assignedToPropName | name | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | enclosingFunctionBody | req res res send data compiledBenign name req params name | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:36:9:36:21 | '/some/path3' | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:36:24:38:1 | functio ... s ok)\\n} | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | CalleeFlexibleAccessPath | res.send | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | enclosingFunctionBody | req res res send data compiledUnknown name req params name | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:37:14:37:60 | data.co ... name }) | receiverName | res | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | CalleeFlexibleAccessPath | data.compiledUnknown | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | enclosingFunctionBody | req res res send data compiledUnknown name req params name | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } | receiverName | data | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | CalleeFlexibleAccessPath | data.compiledUnknown | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | InputAccessPathFromCallee | 0.name | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | assignedToPropName | name | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | enclosingFunctionBody | req res res send data compiledUnknown name req params name | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:40:9:40:21 | '/some/path4' | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:40:24:45:1 | functio ... }));\\n} | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | CalleeFlexibleAccessPath | res.send | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | enclosingFunctionBody | req res res send data compiledMixed prefix >>> path req params path | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:41:14:44:6 | data.co ... \\n }) | receiverName | res | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | enclosingFunctionBody | req res res send data compiledMixed prefix >>> path req params path | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } | receiverName | data | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | InputAccessPathFromCallee | 0.prefix | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | assignedToPropName | prefix | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | enclosingFunctionBody | req res res send data compiledMixed prefix >>> path req params path | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:42:17:42:22 | ">>> " | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | InputAccessPathFromCallee | 0.path | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | assignedToPropName | path | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | enclosingFunctionBody | req res res send data compiledMixed prefix >>> path req params path | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:47:9:47:21 | '/some/path5' | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | calleeImports | express | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:47:24:52:1 | functio ... }));\\n} | receiverName | app | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | CalleeFlexibleAccessPath | res.send | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | enclosingFunctionBody | req res res send data compiledMixed prefix req params prefix path data/path-5.txt | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:48:14:51:6 | data.co ... \\n }) | receiverName | res | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | enclosingFunctionBody | req res res send data compiledMixed prefix req params prefix path data/path-5.txt | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } | receiverName | data | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | InputAccessPathFromCallee | 0.prefix | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | assignedToPropName | prefix | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | enclosingFunctionBody | req res res send data compiledMixed prefix req params prefix path data/path-5.txt | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix | fileImports | express fs handlebars | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | CalleeFlexibleAccessPath | data.compiledMixed | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | InputAccessPathFromCallee | 0.path | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | assignedToPropName | path | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | contextFunctionInterfaces | catFile(filePath)\ninit()\nprependToLines(prefix, filePath) | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | enclosingFunctionBody | req res res send data compiledMixed prefix req params prefix path data/path-5.txt | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/handlebars.js:50:15:50:31 | "data/path-5.txt" | fileImports | express fs handlebars | | autogenerated/TaintedPath/my-async-fs-module.js:1:20:1:23 | 'fs' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/my-async-fs-module.js:1:20:1:23 | 'fs' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/my-async-fs-module.js:1:20:1:23 | 'fs' | calleeImports | | @@ -5660,44 +7399,44 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:1:18:1:21 | 'fs' | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:1:18:1:21 | 'fs' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:1:18:1:21 | 'fs' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:1:18:1:21 | 'fs' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:1:18:1:21 | 'fs' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:2:23:2:31 | 'express' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:3:19:3:23 | 'url' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:4:24:4:42 | 'sanitize-filename' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:5:26:5:31 | 'path' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:10:9:10:16 | '/basic' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:10:19:18:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | InputArgumentIndex | 0 | @@ -5706,7 +7445,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:13:19:13:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | InputArgumentIndex | 0 | @@ -5715,7 +7454,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:14:19:14:29 | './' + path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | InputArgumentIndex | 0 | @@ -5724,7 +7463,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:15:19:15:38 | path + '/index.html' | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | InputArgumentIndex | 0 | @@ -5733,7 +7472,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:16:19:16:53 | pathMod ... .html') | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | InputArgumentIndex | 0 | @@ -5742,7 +7481,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:16:35:16:38 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | InputArgumentIndex | 1 | @@ -5751,7 +7490,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:16:41:16:52 | 'index.html' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | InputArgumentIndex | 0 | @@ -5760,7 +7499,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:17:19:17:57 | pathMod ... , path) | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | InputArgumentIndex | 0 | @@ -5769,7 +7508,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:17:35:17:50 | '/home/user/www' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | InputArgumentIndex | 1 | @@ -5778,27 +7517,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:17:53:17:56 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:20:9:20:20 | '/normalize' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:20:23:28:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | calleeImports | path | @@ -5806,7 +7545,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:21:35:21:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | InputArgumentIndex | 0 | @@ -5815,7 +7554,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:23:19:23:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | InputArgumentIndex | 0 | @@ -5824,7 +7563,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:24:19:24:29 | './' + path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | InputArgumentIndex | 0 | @@ -5833,7 +7572,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:25:19:25:38 | path + '/index.html' | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | InputArgumentIndex | 0 | @@ -5842,7 +7581,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:26:19:26:53 | pathMod ... .html') | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | InputArgumentIndex | 0 | @@ -5851,7 +7590,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:26:35:26:38 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | InputArgumentIndex | 1 | @@ -5860,7 +7599,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:26:41:26:52 | 'index.html' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | InputArgumentIndex | 0 | @@ -5869,7 +7608,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:27:19:27:57 | pathMod ... , path) | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | InputArgumentIndex | 0 | @@ -5878,7 +7617,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:27:35:27:50 | '/home/user/www' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | InputArgumentIndex | 1 | @@ -5887,27 +7626,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | enclosingFunctionBody | req res path pathModule normalize req query path fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html fs readFileSync pathModule join path index.html fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:27:53:27:56 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:30:9:30:32 | '/norma ... solute' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:30:35:51:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | calleeImports | path | @@ -5915,7 +7654,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:31:35:31:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | InputArgumentIndex | 0 | @@ -5924,7 +7663,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:36:19:36:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | InputArgumentIndex | 0 | @@ -5933,7 +7672,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:38:24:38:26 | "." | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | InputArgumentIndex | 0 | @@ -5942,7 +7681,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:39:21:39:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | InputArgumentIndex | 0 | @@ -5951,7 +7690,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:41:21:41:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | InputArgumentIndex | 0 | @@ -5960,7 +7699,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:43:24:43:27 | ".." | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | InputArgumentIndex | 0 | @@ -5969,7 +7708,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:44:21:44:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | InputArgumentIndex | 0 | @@ -5978,7 +7717,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:46:24:46:28 | "../" | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | InputArgumentIndex | 0 | @@ -5987,7 +7726,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:47:21:47:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | InputArgumentIndex | 0 | @@ -5996,7 +7735,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:49:24:49:44 | ".." + ... ule.sep | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | InputArgumentIndex | 0 | @@ -6005,27 +7744,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path fs readFileSync path path startsWith . fs readFileSync path fs readFileSync path path startsWith .. fs readFileSync path path startsWith ../ fs readFileSync path path startsWith .. pathModule sep fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:50:21:50:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:53:9:53:36 | '/norma ... DotDot' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:53:39:69:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | calleeImports | path | @@ -6033,7 +7772,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:54:35:54:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | InputArgumentIndex | 0 | @@ -6042,7 +7781,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:56:23:56:26 | ".." | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | InputArgumentIndex | 0 | @@ -6051,7 +7790,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:59:19:59:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | InputArgumentIndex | 0 | @@ -6060,7 +7799,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:61:19:61:29 | "./" + path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | InputArgumentIndex | 0 | @@ -6069,7 +7808,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:63:19:63:38 | path + "/index.html" | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | InputArgumentIndex | 0 | @@ -6078,7 +7817,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:66:21:66:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | InputArgumentIndex | 0 | @@ -6087,27 +7826,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync ./ path fs readFileSync path /index.html pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:68:21:68:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:71:9:71:28 | '/prepend-normalize' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:71:31:79:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize ./ req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | calleeImports | path | @@ -6115,7 +7854,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | enclosingFunctionBody | req res path pathModule normalize ./ req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:73:35:73:55 | './' + ... ry.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | InputArgumentIndex | 0 | @@ -6124,7 +7863,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | enclosingFunctionBody | req res path pathModule normalize ./ req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:75:24:75:27 | ".." | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | InputArgumentIndex | 0 | @@ -6133,7 +7872,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | enclosingFunctionBody | req res path pathModule normalize ./ req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:76:21:76:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | InputArgumentIndex | 0 | @@ -6142,21 +7881,21 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | enclosingFunctionBody | req res path pathModule normalize ./ req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:78:22:78:25 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:81:9:81:19 | '/absolute' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:81:22:91:1 | (req, r ... '../'\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -6164,7 +7903,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | enclosingFunctionBody | req res path req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:87:13:87:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | InputArgumentIndex | 0 | @@ -6173,7 +7912,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:87:29:87:32 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6181,7 +7920,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:89:23:89:38 | '/home/user/www' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -6189,7 +7928,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | enclosingFunctionBody | req res path req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:90:15:90:35 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | InputArgumentIndex | 0 | @@ -6198,27 +7937,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:90:31:90:34 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:93:9:93:30 | '/norma ... solute' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:93:33:103:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | calleeImports | path | @@ -6226,7 +7965,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:94:35:94:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -6234,7 +7973,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:99:13:99:33 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | InputArgumentIndex | 0 | @@ -6243,7 +7982,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:99:29:99:32 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6252,7 +7991,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:101:23:101:38 | '/home/user/www' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | CalleeFlexibleAccessPath | res.write | | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | InputArgumentIndex | 0 | @@ -6260,7 +7999,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:102:15:102:35 | fs.read ... c(path) | receiverName | res | | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | InputArgumentIndex | 0 | @@ -6269,27 +8008,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path res write fs readFileSync path path startsWith /home/user/www res write fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:102:31:102:34 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:105:9:105:25 | '/combined-check' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:105:28:114:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith /home/user/www fs readFileSync path path 0 0 / path 0 0 . fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:106:14:106:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | calleeImports | path | @@ -6297,7 +8036,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith /home/user/www fs readFileSync path path 0 0 / path 0 0 . fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:106:35:106:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | InputArgumentIndex | 0 | @@ -6306,7 +8045,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith /home/user/www fs readFileSync path path 0 0 / path 0 0 . fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:109:23:109:38 | "/home/user/www" | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | InputArgumentIndex | 0 | @@ -6315,7 +8054,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith /home/user/www fs readFileSync path path 0 0 / path 0 0 . fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:110:21:110:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | InputArgumentIndex | 0 | @@ -6324,27 +8063,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path startsWith /home/user/www fs readFileSync path path 0 0 / path 0 0 . fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:113:21:113:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:116:9:116:19 | '/realpath' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:116:22:127:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | CalleeFlexibleAccessPath | fs.realpathSync | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | calleeImports | fs | @@ -6352,7 +8091,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:117:30:117:43 | req.query.path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | InputArgumentIndex | 0 | @@ -6361,7 +8100,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:119:19:119:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | InputArgumentIndex | 0 | @@ -6370,7 +8109,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:120:19:120:53 | pathMod ... .html') | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | InputArgumentIndex | 0 | @@ -6379,7 +8118,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:120:35:120:38 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | InputArgumentIndex | 1 | @@ -6388,7 +8127,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:120:41:120:52 | 'index.html' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | InputArgumentIndex | 0 | @@ -6397,7 +8136,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:122:23:122:38 | "/home/user/www" | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | InputArgumentIndex | 0 | @@ -6406,7 +8145,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:123:21:123:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | InputArgumentIndex | 0 | @@ -6415,7 +8154,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:125:19:125:44 | pathMod ... , path) | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | InputArgumentIndex | 0 | @@ -6424,7 +8163,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:125:35:125:37 | '.' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | InputArgumentIndex | 1 | @@ -6433,7 +8172,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:125:40:125:43 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | InputArgumentIndex | 0 | @@ -6442,7 +8181,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:126:19:126:57 | pathMod ... , path) | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6451,7 +8190,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:126:35:126:50 | '/home/user/www' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | InputArgumentIndex | 1 | @@ -6460,27 +8199,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | enclosingFunctionBody | req res path fs realpathSync req query path fs readFileSync path fs readFileSync pathModule join path index.html path startsWith /home/user/www fs readFileSync path fs readFileSync pathModule join . path fs readFileSync pathModule join /home/user/www path | | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:126:53:126:56 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:129:9:129:26 | '/coerce-relative' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:129:29:136:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | calleeImports | path | @@ -6488,7 +8227,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:130:30:130:32 | '.' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | InputArgumentIndex | 1 | @@ -6497,7 +8236,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:130:35:130:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | InputArgumentIndex | 0 | @@ -6506,7 +8245,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:132:24:132:27 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | InputArgumentIndex | 0 | @@ -6515,7 +8254,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:133:21:133:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | InputArgumentIndex | 0 | @@ -6524,27 +8263,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | enclosingFunctionBody | req res path pathModule join . req query path path startsWith .. fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:135:21:135:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:138:9:138:26 | '/coerce-absolute' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:138:29:145:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | calleeImports | path | @@ -6552,7 +8291,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:139:30:139:45 | '/home/user/www' | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | InputArgumentIndex | 1 | @@ -6561,7 +8300,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:139:48:139:61 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6570,7 +8309,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:141:23:141:38 | '/home/user/www' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | InputArgumentIndex | 0 | @@ -6579,7 +8318,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:142:21:142:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | InputArgumentIndex | 0 | @@ -6588,27 +8327,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | enclosingFunctionBody | req res path pathModule join /home/user/www req query path path startsWith /home/user/www fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:144:21:144:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:147:9:147:37 | '/conca ... zation' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:147:40:157:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | calleeImports | path | @@ -6616,7 +8355,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:148:44:148:57 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | InputArgumentIndex | 0 | @@ -6625,7 +8364,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:150:24:150:27 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | InputArgumentIndex | 0 | @@ -6634,7 +8373,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:151:21:151:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | InputArgumentIndex | 0 | @@ -6643,7 +8382,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:153:21:153:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | CalleeFlexibleAccessPath | path.includes | | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | InputArgumentIndex | 0 | @@ -6652,7 +8391,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:155:22:155:25 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | InputArgumentIndex | 0 | @@ -6661,27 +8400,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | enclosingFunctionBody | req res path foo/ pathModule normalize req query path path startsWith .. fs readFileSync path fs readFileSync path path includes .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:156:21:156:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:159:9:159:19 | '/noDotDot' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:159:22:171:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | calleeImports | path | @@ -6689,7 +8428,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:160:35:160:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | CalleeFlexibleAccessPath | path.includes | | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | InputArgumentIndex | 0 | @@ -6698,7 +8437,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:162:21:162:24 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | InputArgumentIndex | 0 | @@ -6707,7 +8446,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:165:19:165:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | InputArgumentIndex | 0 | @@ -6716,7 +8455,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:168:21:168:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | InputArgumentIndex | 0 | @@ -6725,21 +8464,21 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path path includes .. fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:170:21:170:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:173:9:173:26 | '/join-regression' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:173:29:211:1 | (req, r ... OT OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | InputArgumentIndex | 0 | @@ -6747,7 +8486,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:180:23:180:25 | '/' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | InputArgumentIndex | 0 | @@ -6755,7 +8494,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:181:23:181:26 | '/x' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | InputArgumentIndex | 0 | @@ -6763,7 +8502,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:182:23:182:25 | '.' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | InputArgumentIndex | 0 | @@ -6772,7 +8511,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:184:19:184:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | InputArgumentIndex | 0 | @@ -6781,7 +8520,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:187:21:187:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | InputArgumentIndex | 0 | @@ -6790,7 +8529,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:189:21:189:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | CalleeFlexibleAccessPath | path.includes | | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | InputArgumentIndex | 0 | @@ -6798,7 +8537,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:191:21:191:24 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | InputArgumentIndex | 0 | @@ -6807,7 +8546,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:192:21:192:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | InputArgumentIndex | 0 | @@ -6816,7 +8555,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:194:21:194:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | CalleeFlexibleAccessPath | path.includes | | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | InputArgumentIndex | 0 | @@ -6824,7 +8563,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:196:22:196:25 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | InputArgumentIndex | 0 | @@ -6833,7 +8572,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:197:21:197:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | InputArgumentIndex | 0 | @@ -6842,7 +8581,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:199:21:199:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | InputArgumentIndex | 0 | @@ -6851,7 +8590,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:201:45:201:48 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | CalleeFlexibleAccessPath | normalizedPath.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6860,7 +8599,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:202:33:202:48 | '/home/user/www' | receiverName | normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | InputArgumentIndex | 0 | @@ -6869,7 +8608,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:203:21:203:34 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | InputArgumentIndex | 0 | @@ -6878,7 +8617,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:205:21:205:34 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | CalleeFlexibleAccessPath | normalizedPath.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | InputArgumentIndex | 0 | @@ -6887,7 +8626,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:207:33:207:48 | '/home/user/www' | receiverName | normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | CalleeFlexibleAccessPath | normalizedPath.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | InputArgumentIndex | 0 | @@ -6896,7 +8635,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:207:80:207:98 | '/home/user/public' | receiverName | normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | InputArgumentIndex | 0 | @@ -6905,7 +8644,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:208:21:208:34 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | InputArgumentIndex | 0 | @@ -6914,27 +8653,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | enclosingFunctionBody | req res path req query path pathModule isAbsolute path path path path startsWith / path path path startsWith /x path path path startsWith . path path fs readFileSync path pathModule isAbsolute path fs readFileSync path fs readFileSync path path includes .. fs readFileSync path fs readFileSync path path includes .. pathModule isAbsolute path fs readFileSync path fs readFileSync path normalizedPath pathModule normalize path normalizedPath startsWith /home/user/www fs readFileSync normalizedPath fs readFileSync normalizedPath normalizedPath startsWith /home/user/www normalizedPath startsWith /home/user/public fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:210:21:210:34 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:213:9:213:37 | '/decod ... zation' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:213:40:223:1 | (req, r ... lized\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | calleeImports | path | @@ -6942,7 +8681,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:214:35:214:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | InputArgumentIndex | 0 | @@ -6951,7 +8690,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:216:56:216:59 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | InputArgumentIndex | 0 | @@ -6960,27 +8699,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:217:21:217:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | CalleeFlexibleAccessPath | decodeURIComponent | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:219:29:219:32 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | CalleeFlexibleAccessPath | path.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:221:56:221:59 | '..' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | InputArgumentIndex | 0 | @@ -6989,27 +8728,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path pathModule isAbsolute path path startsWith .. fs readFileSync path path decodeURIComponent path pathModule isAbsolute path path startsWith .. fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:222:21:222:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:225:9:225:18 | '/replace' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:225:21:233:1 | (req, r ... K\\n }\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | calleeImports | path | @@ -7017,7 +8756,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:226:35:226:48 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | InputArgumentIndex | 0 | @@ -7026,7 +8765,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:226:59:226:64 | /%20/g | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | CalleeFlexibleAccessPath | pathModule.normalize().replace | | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | calleeImports | path | @@ -7034,7 +8773,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:226:67:226:69 | ' ' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | calleeImports | fs | @@ -7042,13 +8781,13 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:228:21:228:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:230:12:230:36 | path.re ... /g, '') | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | calleeImports | path | @@ -7056,7 +8795,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:230:25:230:31 | /\\.\\./g | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | CalleeFlexibleAccessPath | path.replace | | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | InputArgumentIndex | 1 | @@ -7065,7 +8804,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:230:34:230:35 | '' | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | InputArgumentIndex | 0 | @@ -7074,27 +8813,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | enclosingFunctionBody | req res path pathModule normalize req query path replace /%20/g pathModule isAbsolute path fs readFileSync path path path replace /\\.\\./g fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:231:21:231:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:235:9:235:23 | '/resolve-path' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:235:26:251:1 | (req, r ... arity\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:236:14:236:47 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | calleeImports | path | @@ -7102,7 +8841,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:236:33:236:46 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | InputArgumentIndex | 0 | @@ -7111,7 +8850,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:238:19:238:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | CalleeFlexibleAccessPath | path.substring | | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | InputArgumentIndex | 0 | @@ -7120,7 +8859,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:242:22:242:22 | 0 | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | CalleeFlexibleAccessPath | path.substring | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | InputArgumentIndex | 1 | @@ -7129,7 +8868,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:242:25:242:39 | self.dir.length | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | InputArgumentIndex | 0 | @@ -7138,7 +8877,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:243:21:243:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | InputArgumentIndex | 0 | @@ -7147,7 +8886,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:245:21:245:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | CalleeFlexibleAccessPath | path.slice | | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | InputArgumentIndex | 0 | @@ -7156,7 +8895,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:247:18:247:18 | 0 | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | CalleeFlexibleAccessPath | path.slice | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | InputArgumentIndex | 1 | @@ -7165,7 +8904,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:247:21:247:35 | self.dir.length | receiverName | path | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | InputArgumentIndex | 0 | @@ -7174,7 +8913,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:248:21:248:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | InputArgumentIndex | 0 | @@ -7183,27 +8922,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something path substring 0 self dir length self dir fs readFileSync path fs readFileSync path path slice 0 self dir length self dir fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:250:21:250:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:253:9:253:30 | '/relat ... tswith' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:253:33:298:1 | (req, r ... \\n }\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:254:14:254:47 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | calleeImports | path | @@ -7211,7 +8950,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:254:33:254:46 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | InputArgumentIndex | 0 | @@ -7220,7 +8959,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:256:19:256:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | InputArgumentIndex | 0 | @@ -7229,7 +8968,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:260:38:260:49 | self.webroot | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | InputArgumentIndex | 1 | @@ -7238,7 +8977,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:260:52:260:55 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | CalleeFlexibleAccessPath | relative.startsWith | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | InputArgumentIndex | 0 | @@ -7247,7 +8986,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:261:26:261:46 | ".." + ... ule.sep | receiverName | relative | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | InputArgumentIndex | 0 | @@ -7256,7 +8995,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:262:21:262:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | InputArgumentIndex | 0 | @@ -7265,7 +9004,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:264:21:264:24 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | InputArgumentIndex | 0 | @@ -7274,7 +9013,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:267:38:267:41 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | InputArgumentIndex | 0 | @@ -7283,7 +9022,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:268:42:268:75 | pathMod ... aceDir) | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | InputArgumentIndex | 0 | @@ -7292,7 +9031,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:268:63:268:74 | workspaceDir | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | InputArgumentIndex | 1 | @@ -7301,7 +9040,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:268:78:268:84 | newpath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | CalleeFlexibleAccessPath | relativePath.indexOf | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | InputArgumentIndex | 0 | @@ -7310,7 +9049,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:269:28:269:48 | '..' + ... ule.sep | receiverName | relativePath | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | InputArgumentIndex | 0 | @@ -7319,7 +9058,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:270:21:270:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | InputArgumentIndex | 0 | @@ -7328,7 +9067,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:272:21:272:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | InputArgumentIndex | 0 | @@ -7337,7 +9076,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:275:38:275:41 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | InputArgumentIndex | 0 | @@ -7346,7 +9085,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:276:42:276:75 | pathMod ... aceDir) | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | InputArgumentIndex | 0 | @@ -7355,7 +9094,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:276:63:276:74 | workspaceDir | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | InputArgumentIndex | 1 | @@ -7364,7 +9103,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:276:78:276:84 | newpath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | CalleeFlexibleAccessPath | relativePath.indexOf | | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | InputArgumentIndex | 0 | @@ -7373,7 +9112,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:277:28:277:32 | '../' | receiverName | relativePath | | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | InputArgumentIndex | 0 | @@ -7382,7 +9121,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:278:21:278:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | InputArgumentIndex | 0 | @@ -7391,7 +9130,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:280:21:280:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | InputArgumentIndex | 0 | @@ -7400,7 +9139,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:283:38:283:41 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | InputArgumentIndex | 0 | @@ -7409,7 +9148,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:284:42:284:75 | pathMod ... aceDir) | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | InputArgumentIndex | 0 | @@ -7418,7 +9157,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:284:63:284:74 | workspaceDir | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | InputArgumentIndex | 1 | @@ -7427,7 +9166,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:284:78:284:84 | newpath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | InputArgumentIndex | 0 | @@ -7436,7 +9175,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:285:28:285:39 | relativePath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | CalleeFlexibleAccessPath | pathModule.normalize().indexOf | | autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | InputArgumentIndex | 0 | @@ -7445,7 +9184,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:285:50:285:54 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | calleeImports | fs | @@ -7453,7 +9192,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:286:21:286:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | InputArgumentIndex | 0 | @@ -7462,7 +9201,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:288:21:288:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | InputArgumentIndex | 0 | @@ -7471,7 +9210,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:291:38:291:41 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | InputArgumentIndex | 0 | @@ -7480,7 +9219,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:292:42:292:75 | pathMod ... aceDir) | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | InputArgumentIndex | 0 | @@ -7489,7 +9228,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:292:63:292:74 | workspaceDir | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | CalleeFlexibleAccessPath | pathModule.relative | | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | InputArgumentIndex | 1 | @@ -7498,7 +9237,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:292:78:292:84 | newpath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | CalleeFlexibleAccessPath | pathModule.normalize | | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | InputArgumentIndex | 0 | @@ -7507,7 +9246,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:293:28:293:39 | relativePath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | CalleeFlexibleAccessPath | pathModule.normalize().indexOf | | autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | InputArgumentIndex | 0 | @@ -7516,7 +9255,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:293:50:293:54 | '../' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | calleeImports | fs | @@ -7524,7 +9263,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:294:21:294:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | InputArgumentIndex | 0 | @@ -7533,33 +9272,33 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path self something relative pathModule relative self webroot path relative startsWith .. pathModule sep relative .. fs readFileSync path fs readFileSync path newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf .. pathModule sep 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ 0 fs readFileSync newpath fs readFileSync newpath newpath pathModule normalize path relativePath pathModule relative pathModule normalize workspaceDir newpath pathModule normalize relativePath indexOf ../ fs readFileSync newpath fs readFileSync newpath | | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:296:21:296:27 | newpath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:300:28:300:43 | "is-path-inside" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | calleeImports | | | autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:301:28:301:43 | "path-is-inside" | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:302:9:302:32 | '/pseud ... ations' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:302:35:336:1 | (req, r ... \\n\\n\\t}\\n\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | InputArgumentIndex | 0 | @@ -7568,7 +9307,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:304:18:304:21 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | InputArgumentIndex | 0 | @@ -7577,7 +9316,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:306:19:306:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | InputArgumentIndex | 0 | @@ -7586,7 +9325,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:309:19:309:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | InputArgumentIndex | 0 | @@ -7595,7 +9334,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | calleeImports | path-is-inside | @@ -7603,7 +9342,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:312:25:312:28 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | calleeImports | fs | @@ -7611,7 +9350,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:313:19:313:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | InputArgumentIndex | 0 | @@ -7620,7 +9359,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:316:19:316:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | InputArgumentIndex | 0 | @@ -7629,7 +9368,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:320:39:320:42 | SAFE | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | InputArgumentIndex | 1 | @@ -7638,7 +9377,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:320:45:320:48 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | InputArgumentIndex | 0 | @@ -7647,7 +9386,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | calleeImports | path-is-inside | @@ -7655,7 +9394,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:321:35:321:38 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | calleeImports | fs | @@ -7663,7 +9402,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:322:19:322:32 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | InputArgumentIndex | 0 | @@ -7672,7 +9411,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:325:19:325:32 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | InputArgumentIndex | 0 | @@ -7681,7 +9420,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | CalleeFlexibleAccessPath | pathIsInside | | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | calleeImports | path-is-inside | @@ -7689,7 +9428,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:328:35:328:38 | SAFE | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | calleeImports | fs | @@ -7697,7 +9436,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:329:19:329:32 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | InputArgumentIndex | 0 | @@ -7706,27 +9445,27 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | enclosingFunctionBody | req res path req query path fs readFileSync path isPathInside path SAFE fs readFileSync path fs readFileSync path pathIsInside path SAFE fs readFileSync path fs readFileSync path normalizedPath pathModule join SAFE path pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath pathIsInside normalizedPath SAFE fs readFileSync normalizedPath fs readFileSync normalizedPath | | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:332:19:332:32 | normalizedPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:338:9:338:29 | '/yet-a ... prefix' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:338:32:350:1 | (req, r ... // OK\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | calleeImports | path | @@ -7734,7 +9473,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:339:32:339:45 | req.query.path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | InputArgumentIndex | 0 | @@ -7743,7 +9482,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:341:18:341:21 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | CalleeFlexibleAccessPath | pathModule.resolve | | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | InputArgumentIndex | 0 | @@ -7752,7 +9491,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:343:31:343:34 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | CalleeFlexibleAccessPath | abs.indexOf | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | InputArgumentIndex | 0 | @@ -7761,7 +9500,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:345:18:345:21 | root | receiverName | abs | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | InputArgumentIndex | 0 | @@ -7770,7 +9509,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:346:19:346:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | InputArgumentIndex | 0 | @@ -7779,21 +9518,21 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | enclosingFunctionBody | req res path pathModule resolve req query path fs readFileSync path abs pathModule resolve path abs indexOf root 0 fs readFileSync path fs readFileSync path | | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:349:18:349:21 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:353:9:353:30 | '/yet-a ... refix2' | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | calleeImports | express | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:353:33:373:1 | (req, r ... ;\\n }\\n} | receiverName | app | | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | InputArgumentIndex | 0 | @@ -7802,7 +9541,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:356:19:356:22 | path | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | InputArgumentIndex | 0 | @@ -7811,7 +9550,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:358:37:358:44 | rootPath | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | CalleeFlexibleAccessPath | pathModule.join | | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | InputArgumentIndex | 1 | @@ -7820,7 +9559,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:358:47:358:50 | path | receiverName | pathModule | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | CalleeFlexibleAccessPath | allowPath | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | InputArgumentIndex | 0 | @@ -7828,14 +9567,14 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:361:18:361:28 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | CalleeFlexibleAccessPath | allowPath | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | InputArgumentIndex | 1 | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | contextFunctionInterfaces | allowPath(requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:361:31:361:38 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | InputArgumentIndex | 0 | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | calleeImports | fs | @@ -7843,7 +9582,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:363:21:363:31 | requestPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | InputArgumentIndex | 0 | @@ -7852,7 +9591,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:366:21:366:31 | requestPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | InputArgumentIndex | 0 | @@ -7861,7 +9600,7 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:368:19:368:28 | targetPath | receiverName | fs | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | CalleeFlexibleAccessPath | requestPath.indexOf | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | InputArgumentIndex | 0 | @@ -7869,50 +9608,217 @@ tokenFeatures | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | contextSurroundingFunctionParameters | (requestPath, rootPath) | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | enclosingFunctionBody | req res path req query path fs readFileSync path requestPath pathModule join rootPath path targetPath allowPath requestPath rootPath targetPath rootPath fs readFileSync requestPath targetPath requestPath fs readFileSync requestPath fs readFileSync targetPath allowPath requestPath rootPath requestPath indexOf rootPath 0 | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename url | +| autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | | autogenerated/TaintedPath/normalizedPaths.js:371:32:371:39 | rootPath | receiverName | requestPath | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | calleeImports | express | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:376:9:376:22 | '/slash-stuff' | receiverName | app | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | calleeImports | express | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:376:25:382:1 | (req, r ... OT OK\\n} | receiverName | app | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync slash path | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:379:19:379:22 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync slash path | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:381:19:381:29 | slash(path) | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | CalleeFlexibleAccessPath | slash | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | calleeImports | slash | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | enclosingFunctionBody | req res path req query path fs readFileSync path fs readFileSync slash path | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | calleeImports | express | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:384:9:384:24 | '/dotdot-regexp' | receiverName | app | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | calleeImports | express | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:384:27:404:1 | (req, r ... K\\n }\\n} | receiverName | app | +| autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | CalleeFlexibleAccessPath | pathModule.normalize | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:385:35:385:45 | req.query.x | receiverName | pathModule | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:388:19:388:22 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | CalleeFlexibleAccessPath | path.match | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:389:19:389:22 | /\\./ | receiverName | path | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:390:21:390:24 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | CalleeFlexibleAccessPath | path.match | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:392:19:392:24 | /\\.\\./ | receiverName | path | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:393:21:393:24 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | CalleeFlexibleAccessPath | path.match | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:395:19:395:26 | /\\.\\.\\// | receiverName | path | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:396:21:396:24 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | CalleeFlexibleAccessPath | path.match | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:398:19:398:29 | /\\.\\.\\/foo/ | receiverName | path | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:399:21:399:24 | path | receiverName | fs | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | CalleeFlexibleAccessPath | path.match | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | calleeImports | path | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:401:19:401:35 | /(\\.\\.\\/\|\\.\\.\\\\)/ | receiverName | path | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | calleeImports | fs | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | contextFunctionInterfaces | allowPath(requestPath, rootPath) | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | enclosingFunctionBody | req res path pathModule normalize req query x pathModule isAbsolute path fs readFileSync path path match /\\./ fs readFileSync path path match /\\.\\./ fs readFileSync path path match /\\.\\.\\// fs readFileSync path path match /\\.\\.\\/foo/ fs readFileSync path path match /(\\.\\.\\/\|\\.\\.\\\\)/ fs readFileSync path | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | fileImports | express fs is-path-inside path path-is-inside sanitize-filename slash url | +| autogenerated/TaintedPath/normalizedPaths.js:402:21:402:24 | path | receiverName | fs | | autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:1:20:1:25 | "http" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:2:17:2:21 | "url" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:3:16:3:19 | "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:4:24:4:36 | "graceful-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:5:21:5:30 | "fs-extra" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:6:24:6:36 | "original-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | calleeImports | http | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:8:32:25:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | InputArgumentIndex | 0 | @@ -7921,7 +9827,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:9:24:9:30 | req.url | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | InputArgumentIndex | 1 | @@ -7930,7 +9836,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:9:33:9:36 | true | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | InputArgumentIndex | 0 | @@ -7939,7 +9845,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:11:19:11:22 | path | receiverName | fs | | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | CalleeFlexibleAccessPath | gracefulFs.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | InputArgumentIndex | 0 | @@ -7948,7 +9854,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:12:27:12:30 | path | receiverName | gracefulFs | | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | CalleeFlexibleAccessPath | fsExtra.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | InputArgumentIndex | 0 | @@ -7957,7 +9863,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:13:24:13:27 | path | receiverName | fsExtra | | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | CalleeFlexibleAccessPath | originalFs.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | InputArgumentIndex | 0 | @@ -7966,7 +9872,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:14:27:14:30 | path | receiverName | originalFs | | autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | CalleeFlexibleAccessPath | getFsModule().readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | InputArgumentIndex | 0 | @@ -7974,14 +9880,14 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:16:34:16:37 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | CalleeFlexibleAccessPath | getFsModule().readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:17:35:17:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | calleeImports | | @@ -7989,7 +9895,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:19:11:19:26 | "./my-fs-module" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | CalleeFlexibleAccessPath | import("p").require().readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | calleeImports | ./my-fs-module | @@ -7997,7 +9903,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:19:56:19:59 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | calleeImports | | @@ -8005,7 +9911,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:21:36:23:10 | process ... : "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | CalleeFlexibleAccessPath | flexibleModuleName.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | calleeImports | | @@ -8013,7 +9919,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path gracefulFs readFileSync path fsExtra readFileSync path originalFs readFileSync path getFsModule true readFileSync path getFsModule false readFileSync path require ./my-fs-module require true readFileSync path flexibleModuleName require process electron versions electron original-fs fs flexibleModuleName readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:24:35:24:38 | path | receiverName | flexibleModuleName | | autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | InputArgumentIndex | 0 | @@ -8022,7 +9928,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | contextSurroundingFunctionParameters | (special) | | autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | enclosingFunctionBody | special special require fs require original-fs | | autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | enclosingFunctionName | getFsModule | -| autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:29:20:29:23 | "fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | calleeImports | | @@ -8030,19 +9936,19 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | contextSurroundingFunctionParameters | (special) | | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | enclosingFunctionBody | special special require fs require original-fs | | autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | enclosingFunctionName | getFsModule | -| autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:31:20:31:32 | "original-fs" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:35:20:35:25 | "util" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | calleeImports | http | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:37:19:43:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | InputArgumentIndex | 0 | @@ -8051,7 +9957,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:38:24:38:30 | req.url | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | InputArgumentIndex | 1 | @@ -8060,7 +9966,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:38:33:38:36 | true | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | CalleeFlexibleAccessPath | util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | InputArgumentIndex | 0 | @@ -8069,7 +9975,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:40:18:40:32 | fs.readFileSync | receiverName | util | | autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | CalleeFlexibleAccessPath | util.promisify() | | autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | InputArgumentIndex | 0 | @@ -8078,7 +9984,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:40:35:40:38 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | calleeImports | | @@ -8086,7 +9992,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:41:11:41:20 | "bluebird" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | CalleeFlexibleAccessPath | import(!).promisify | | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | calleeImports | bluebird | @@ -8094,7 +10000,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:41:33:41:47 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | CalleeFlexibleAccessPath | import(!).promisify() | | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | calleeImports | bluebird | @@ -8102,7 +10008,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:41:50:41:53 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | calleeImports | | @@ -8110,7 +10016,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:42:11:42:20 | "bluebird" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | CalleeFlexibleAccessPath | import(!).promisifyAll | | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | calleeImports | bluebird | @@ -8118,7 +10024,7 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:42:36:42:37 | fs | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | CalleeFlexibleAccessPath | import(!).promisifyAll().readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | calleeImports | bluebird | @@ -8126,56 +10032,370 @@ tokenFeatures | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | enclosingFunctionBody | req res path url parse req url true query path util promisify fs readFileSync path require bluebird promisify fs readFileSync path require bluebird promisifyAll fs readFileSync path | | autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:42:53:42:56 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | calleeImports | | | autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | calleeImports | http | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | contextFunctionInterfaces | getFsModule(special) | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | -| autogenerated/TaintedPath/other-fs-libraries.js:48:19:53:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/other-fs-libraries.js:46:25:46:46 | "./my-a ... module" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:48:19:64:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | calleeImports | url | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path | +| autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:49:24:49:30 | req.url | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | InputArgumentIndex | 1 | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | calleeImports | url | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path | +| autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:49:33:49:36 | true | receiverName | url | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | calleeImports | fs | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path | +| autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:51:19:51:22 | path | receiverName | fs | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | CalleeFlexibleAccessPath | asyncFS.readFileSync | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | InputArgumentIndex | 0 | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | calleeImports | ./my-async-fs-module | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | contextFunctionInterfaces | getFsModule(special) | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path | +| autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http original-fs url util | +| autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | | autogenerated/TaintedPath/other-fs-libraries.js:52:24:52:27 | path | receiverName | asyncFS | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:54:11:54:16 | "pify" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | CalleeFlexibleAccessPath | import(!) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | calleeImports | pify | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:54:19:54:33 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | CalleeFlexibleAccessPath | import(!)() | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | calleeImports | pify | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:54:36:54:39 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:55:11:55:16 | "pify" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | CalleeFlexibleAccessPath | import(!) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | calleeImports | pify | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:55:19:55:20 | fs | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | CalleeFlexibleAccessPath | import(!)().readFileSync | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | calleeImports | pify | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:55:36:55:39 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:57:11:57:26 | 'util.promisify' | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | CalleeFlexibleAccessPath | import(!) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | calleeImports | util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:57:29:57:43 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | CalleeFlexibleAccessPath | import(!)() | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | calleeImports | util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:57:46:57:49 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:59:11:59:19 | "thenify" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | CalleeFlexibleAccessPath | import(!) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | calleeImports | thenify | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:59:22:59:36 | fs.readFileSync | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | CalleeFlexibleAccessPath | import(!)() | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | calleeImports | thenify | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:59:39:59:42 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:61:27:61:36 | 'read-pkg' | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | CalleeFlexibleAccessPath | readPkg.readPackageSync | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | calleeImports | read-pkg | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} | receiverName | readPkg | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | CalleeFlexibleAccessPath | readPkg.readPackageSync | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | InputAccessPathFromCallee | 0.cwd | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | assignedToPropName | cwd | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | calleeImports | read-pkg | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:62:43:62:46 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | CalleeFlexibleAccessPath | readPkg.readPackageAsync | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | calleeImports | read-pkg | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} | receiverName | readPkg | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | CalleeFlexibleAccessPath | readPkg.readPackageAsync | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | InputAccessPathFromCallee | 0.cwd | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | assignedToPropName | cwd | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | calleeImports | read-pkg | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path asyncFS readFileSync path require pify fs readFileSync path require pify fs readFileSync path require util.promisify fs readFileSync path require thenify fs readFileSync path readPkg require read-pkg pkg readPkg readPackageSync cwd path pkgPromise readPkg readPackageAsync cwd path | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:63:51:63:54 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | calleeImports | | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/other-fs-libraries.js:66:24:66:31 | "mkdirp" | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:67:19:73:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | calleeImports | url | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path mkdirp path mkdirp sync path | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:68:24:68:30 | req.url | receiverName | url | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | calleeImports | url | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path mkdirp path mkdirp sync path | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:68:33:68:36 | true | receiverName | url | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | calleeImports | fs | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path mkdirp path mkdirp sync path | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:70:19:70:22 | path | receiverName | fs | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | CalleeFlexibleAccessPath | mkdirp | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | calleeImports | mkdirp | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path mkdirp path mkdirp sync path | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:71:10:71:13 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | CalleeFlexibleAccessPath | mkdirp.sync | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | calleeImports | mkdirp | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | contextFunctionInterfaces | getFsModule(special) | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path mkdirp path mkdirp sync path | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | fileImports | ./my-async-fs-module ./my-fs-module bluebird fs fs-extra graceful-fs http mkdirp original-fs pify read-pkg thenify url util util.promisify | +| autogenerated/TaintedPath/other-fs-libraries.js:72:15:72:18 | path | receiverName | mkdirp | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | calleeImports | | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/prettier.js:1:25:1:33 | 'express' | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | calleeImports | | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/prettier.js:2:26:2:35 | "prettier" | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | calleeImports | express | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:5:9:5:20 | '/some/path' | receiverName | app | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | calleeImports | express | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:5:23:14:1 | functio ... });\\n} | receiverName | app | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | CalleeFlexibleAccessPath | prettier.resolveConfig | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:7:28:7:28 | p | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | CalleeFlexibleAccessPath | prettier.resolveConfig().then | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:7:36:9:5 | (option ... ;\\n } | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | CalleeFlexibleAccessPath | prettier.format | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:8:43:8:47 | "foo" | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | CalleeFlexibleAccessPath | prettier.format | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:8:50:8:56 | options | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | CalleeFlexibleAccessPath | prettier.resolveConfig | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:11:28:11:32 | "foo" | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | CalleeFlexibleAccessPath | prettier.resolveConfig | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:11:35:11:45 | {config: p} | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | CalleeFlexibleAccessPath | prettier.resolveConfig | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | InputAccessPathFromCallee | 1.config | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | assignedToPropName | config | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:11:44:11:44 | p | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | CalleeFlexibleAccessPath | prettier.resolveConfig().then | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:11:53:13:5 | (option ... ;\\n } | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | CalleeFlexibleAccessPath | prettier.format | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:12:43:12:47 | "bar" | receiverName | prettier | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | CalleeFlexibleAccessPath | prettier.format | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | calleeImports | prettier | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | contextFunctionInterfaces | | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | contextSurroundingFunctionParameters | (req, res)\n(options) | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | enclosingFunctionBody | req res p req params prettier resolveConfig p then options formatted prettier format foo options prettier resolveConfig foo config p then options formatted prettier format bar options | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | fileImports | express prettier | +| autogenerated/TaintedPath/prettier.js:12:50:12:56 | options | receiverName | prettier | | autogenerated/TaintedPath/pupeteer.js:1:27:1:37 | 'puppeteer' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/pupeteer.js:1:27:1:37 | 'puppeteer' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/pupeteer.js:1:27:1:37 | 'puppeteer' | calleeImports | | @@ -8248,25 +10468,25 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:1:18:1:21 | 'fs' | calleeImports | | | autogenerated/TaintedPath/tainted-access-paths.js:1:18:1:21 | 'fs' | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-access-paths.js:1:18:1:21 | 'fs' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/tainted-access-paths.js:1:18:1:21 | 'fs' | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:1:18:1:21 | 'fs' | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | calleeImports | | | autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:2:20:2:25 | 'http' | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | calleeImports | | | autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:3:19:3:23 | 'url' | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | calleeImports | http | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:5:32:32:1 | functio ... OT OK\\n} | receiverName | http | | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | InputArgumentIndex | 0 | @@ -8275,7 +10495,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:6:24:6:30 | req.url | receiverName | url | | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | CalleeFlexibleAccessPath | url.parse | | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | InputArgumentIndex | 1 | @@ -8284,7 +10504,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:6:33:6:36 | true | receiverName | url | | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | InputArgumentIndex | 0 | @@ -8293,7 +10513,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:8:19:8:22 | path | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | InputArgumentIndex | 0 | @@ -8302,7 +10522,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:12:19:12:25 | obj.sub | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | InputArgumentIndex | 0 | @@ -8311,7 +10531,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:16:19:16:25 | obj.sub | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | InputArgumentIndex | 0 | @@ -8320,7 +10540,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:20:21:20:28 | obj.sub2 | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | InputArgumentIndex | 0 | @@ -8329,7 +10549,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:26:19:26:26 | obj.sub3 | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | InputArgumentIndex | 0 | @@ -8338,7 +10558,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:29:21:29:28 | obj.sub4 | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | InputArgumentIndex | 0 | @@ -8347,7 +10567,7 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:30:23:30:30 | obj.sub4 | receiverName | fs | | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | CalleeFlexibleAccessPath | fs.readFileSync | | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | InputArgumentIndex | 0 | @@ -8356,8 +10576,111 @@ tokenFeatures | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | enclosingFunctionBody | req res path url parse req url true query path fs readFileSync path obj bla something path fs readFileSync obj sub obj sub safe fs readFileSync obj sub obj sub2 safe random fs readFileSync obj sub2 random obj sub3 safe fs readFileSync obj sub3 obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 fs readFileSync obj sub4 | | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | enclosingFunctionName | http.createServer#functionalargument | -| autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | fileImports | fs http url | +| autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-access-paths.js:31:23:31:30 | obj.sub4 | receiverName | fs | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | calleeImports | | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/tainted-access-paths.js:36:22:36:30 | 'node:fs' | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:38:33:41:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | calleeImports | url | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path nodefs readFileSync path | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:39:24:39:30 | req.url | receiverName | url | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | calleeImports | url | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | enclosingFunctionBody | req res path url parse req url true query path nodefs readFileSync path | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:39:33:39:36 | true | receiverName | url | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | CalleeFlexibleAccessPath | nodefs.readFileSync | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | calleeImports | node:fs | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | enclosingFunctionBody | req res path url parse req url true query path nodefs readFileSync path | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:40:23:40:26 | path | receiverName | nodefs | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | calleeImports | | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/tainted-access-paths.js:45:24:45:31 | "chownr" | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | http.createServer | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | calleeImports | http | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:47:33:50:1 | functio ... OT OK\\n} | receiverName | http | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | calleeImports | url | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:48:24:48:30 | req.url | receiverName | url | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | CalleeFlexibleAccessPath | url.parse | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | calleeImports | url | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:48:33:48:36 | true | receiverName | url | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | CalleeFlexibleAccessPath | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | calleeImports | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:49:10:49:13 | path | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | CalleeFlexibleAccessPath | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | calleeImports | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:49:16:49:24 | "someuid" | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | CalleeFlexibleAccessPath | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | InputArgumentIndex | 2 | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | calleeImports | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:49:27:49:35 | "somegid" | fileImports | chownr fs http node:fs url | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | CalleeFlexibleAccessPath | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | InputArgumentIndex | 3 | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | calleeImports | chownr | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | contextSurroundingFunctionParameters | (req, res)\n(err) | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | enclosingFunctionBody | req res path url parse req url true query path chownr path someuid somegid err | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | enclosingFunctionName | http.createServer#functionalargument | +| autogenerated/TaintedPath/tainted-access-paths.js:49:38:49:54 | function (err) {} | fileImports | chownr fs http node:fs url | | autogenerated/TaintedPath/tainted-array-steps.js:1:18:1:21 | 'fs' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/tainted-array-steps.js:1:18:1:21 | 'fs' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-array-steps.js:1:18:1:21 | 'fs' | calleeImports | | @@ -8475,20 +10798,20 @@ tokenFeatures | autogenerated/TaintedPath/tainted-require.js:1:23:1:31 | 'express' | calleeImports | | | autogenerated/TaintedPath/tainted-require.js:1:23:1:31 | 'express' | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-require.js:1:23:1:31 | 'express' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/tainted-require.js:1:23:1:31 | 'express' | fileImports | express | +| autogenerated/TaintedPath/tainted-require.js:1:23:1:31 | 'express' | fileImports | express resolve | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | calleeImports | express | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | contextSurroundingFunctionParameters | | -| autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | fileImports | express | +| autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | fileImports | express resolve | | autogenerated/TaintedPath/tainted-require.js:5:9:5:20 | '/some/path' | receiverName | app | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | CalleeFlexibleAccessPath | app.get | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | InputArgumentIndex | 1 | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | calleeImports | express | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | contextSurroundingFunctionParameters | (req, res) | -| autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | fileImports | express | +| autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | fileImports | express resolve | | autogenerated/TaintedPath/tainted-require.js:5:23:8:1 | functio ... e"));\\n} | receiverName | app | | autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | InputArgumentIndex | 0 | @@ -8497,15 +10820,94 @@ tokenFeatures | autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | enclosingFunctionBody | req res m require req param module | | autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | fileImports | express | +| autogenerated/TaintedPath/tainted-require.js:7:19:7:37 | req.param("module") | fileImports | express resolve | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | CalleeFlexibleAccessPath | req.param | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | contextFunctionInterfaces | | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | contextSurroundingFunctionParameters | (req, res) | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | enclosingFunctionBody | req res m require req param module | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | enclosingFunctionName | app.get#functionalargument | -| autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | fileImports | express | +| autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | fileImports | express resolve | | autogenerated/TaintedPath/tainted-require.js:7:29:7:36 | "module" | receiverName | req | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | CalleeFlexibleAccessPath | require | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | calleeImports | | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/tainted-require.js:10:25:10:33 | "resolve" | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | calleeImports | express | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | contextSurroundingFunctionParameters | | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:11:9:11:20 | '/some/path' | receiverName | app | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | CalleeFlexibleAccessPath | app.get | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | calleeImports | express | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:11:23:17:1 | functio ... });\\n} | receiverName | app | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | CalleeFlexibleAccessPath | resolve.sync | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | calleeImports | resolve | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:12:29:12:47 | req.param("module") | receiverName | resolve | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | CalleeFlexibleAccessPath | req.param | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:12:39:12:46 | "module" | receiverName | req | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | CalleeFlexibleAccessPath | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | calleeImports | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:14:11:14:29 | req.param("module") | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | CalleeFlexibleAccessPath | req.param | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | InputArgumentIndex | 0 | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:14:21:14:28 | "module" | receiverName | req | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | CalleeFlexibleAccessPath | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | calleeImports | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:14:32:14:53 | { based ... rname } | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | CalleeFlexibleAccessPath | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | InputAccessPathFromCallee | 1.basedir | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | InputArgumentIndex | 1 | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | assignedToPropName | basedir | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | calleeImports | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | contextSurroundingFunctionParameters | (req, res) | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:14:43:14:51 | __dirname | fileImports | express resolve | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | CalleeFlexibleAccessPath | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | InputArgumentIndex | 2 | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | calleeImports | resolve | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | contextFunctionInterfaces | | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | contextSurroundingFunctionParameters | (req, res)\n(err, res) | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | enclosingFunctionBody | req res module resolve sync req param module resolve req param module basedir __dirname err res module res | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | enclosingFunctionName | app.get#functionalargument | +| autogenerated/TaintedPath/tainted-require.js:14:56:16:3 | functio ... es;\\n } | fileImports | express resolve | | autogenerated/TaintedPath/tainted-sendFile.js:1:23:1:31 | 'express' | CalleeFlexibleAccessPath | require | | autogenerated/TaintedPath/tainted-sendFile.js:1:23:1:31 | 'express' | InputArgumentIndex | 0 | | autogenerated/TaintedPath/tainted-sendFile.js:1:23:1:31 | 'express' | calleeImports | | @@ -9390,17 +11792,17 @@ tokenFeatures | autogenerated/TaintedPath/views.js:1:43:1:55 | req.params[0] | receiverName | res | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | CalleeFlexibleAccessPath | this.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | contextSurroundingFunctionParameters | | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:23:1:31 | 'message' | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | this.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | InputArgumentIndex | 1 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (event) | | autogenerated/Xss/DomBasedXss/addEventListener.js:1:34:3:1 | functio ... OT OK\\n} | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | contextSurroundingFunctionParameters | (event) | | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | enclosingFunctionBody | event document write event data | | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | enclosingFunctionName | addEventListener#functionalargument | @@ -9408,17 +11810,17 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/addEventListener.js:2:20:2:29 | event.data | receiverName | document | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | CalleeFlexibleAccessPath | this.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | contextSurroundingFunctionParameters | | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:23:5:31 | 'message' | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | CalleeFlexibleAccessPath | this.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | InputArgumentIndex | 1 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | contextSurroundingFunctionParameters | (?) | | autogenerated/Xss/DomBasedXss/addEventListener.js:5:34:7:1 | functio ... OT OK\\n} | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | contextSurroundingFunctionParameters | (?) | | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | enclosingFunctionBody | data document write data | | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | enclosingFunctionName | addEventListener#functionalargument | @@ -9426,57 +11828,57 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/addEventListener.js:6:20:6:23 | data | receiverName | document | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | contextSurroundingFunctionParameters | (x, event, y) | -| autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:11:24:11:29 | x.data | receiverName | document | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | contextSurroundingFunctionParameters | (x, event, y) | -| autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:12:24:12:33 | event.data | receiverName | document | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | contextSurroundingFunctionParameters | (x, event, y) | -| autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:13:24:13:29 | y.data | receiverName | document | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | CalleeFlexibleAccessPath | window.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:29:16:37 | "message" | receiverName | window | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | CalleeFlexibleAccessPath | window.addEventListener | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | InputArgumentIndex | 1 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:40:16:70 | foo.bin ... tems'}) | receiverName | window | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | CalleeFlexibleAccessPath | foo.bind | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:49:16:52 | null | receiverName | foo | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | CalleeFlexibleAccessPath | foo.bind | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | InputArgumentIndex | 1 | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | fileImports | | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:55:16:69 | {data: 'items'} | receiverName | foo | @@ -9484,11 +11886,35 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | InputAccessPathFromCallee | 1.data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | assignedToPropName | data | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | contextFunctionInterfaces | foo(x, event, y)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items | +| autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/addEventListener.js:16:62:16:68 | 'items' | fileImports | | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | CalleeFlexibleAccessPath | document.write | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | fileImports | | +| autogenerated/Xss/DomBasedXss/addEventListener.js:22:24:22:29 | e.data | receiverName | document | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | CalleeFlexibleAccessPath | mySet.includes | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | fileImports | | +| autogenerated/Xss/DomBasedXss/addEventListener.js:26:28:26:35 | e.origin | receiverName | mySet | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | CalleeFlexibleAccessPath | document.write | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | contextFunctionInterfaces | foo(x, event, y)\nonmessage(e)\nonmessage(e)\ntest() | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | enclosingFunctionBody | foo x event y document write x data document write event data document write y data window addEventListener message foo bind null data items window onmessage e e origin https://foobar.com document write e data window onmessage e mySet includes e origin document write e data | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | fileImports | | +| autogenerated/Xss/DomBasedXss/addEventListener.js:27:28:27:33 | e.data | receiverName | document | | autogenerated/Xss/DomBasedXss/angular2-client.ts:7:13:7:22 | 'app-root' | CalleeFlexibleAccessPath | Component | | autogenerated/Xss/DomBasedXss/angular2-client.ts:7:13:7:22 | 'app-root' | InputAccessPathFromCallee | 0.selector | | autogenerated/Xss/DomBasedXss/angular2-client.ts:7:13:7:22 | 'app-root' | InputArgumentIndex | 0 | @@ -9660,18 +12086,18 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:7:31:7:84 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:7:32:7:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:7:32:7:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:7:32:7:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) | stringConcatenatedWith | 'Hello' | @@ -9680,30 +12106,30 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | calleeImports | classnames | | autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:7:58:7:68 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:7:71:7:83 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:8:31:8:85 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:8:31:8:85 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:8:31:8:85 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:8:32:8:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:8:32:8:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:8:32:8:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) | stringConcatenatedWith | 'Hello' | @@ -9712,30 +12138,30 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | calleeImports | classnames/dedupe | | autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:8:59:8:69 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:8:72:8:84 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:9:31:9:85 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:9:31:9:85 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:9:31:9:85 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:9:32:9:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:9:32:9:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:9:32:9:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) | stringConcatenatedWith | 'Hello' | @@ -9744,12 +12170,12 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | calleeImports | classnames/bind | | autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:9:59:9:69 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:9:72:9:84 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:10:39:10:56 | {foo: window.name} | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:10:39:10:56 | {foo: window.name} | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:10:39:10:56 | {foo: window.name} | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:10:39:10:56 | {foo: window.name} | receiverName | classNames | @@ -9769,24 +12195,24 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | calleeImports | classnames | | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:11:31:11:79 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:11:32:11:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:11:32:11:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:11:32:11:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') | stringConcatenatedWith | 'Hello' | @@ -9795,12 +12221,12 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | calleeImports | classnames | | autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:11:59:11:63 | 'foo' | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:11:66:11:78 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:12:37:12:38 | {} | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:12:37:12:38 | {} | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:12:37:12:38 | {} | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:12:37:12:38 | {} | receiverName | classNames | | autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:13:31:13:83 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:13:32:13:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:13:32:13:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:13:32:13:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) | stringConcatenatedWith | 'Hello' | @@ -9836,30 +12262,30 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | calleeImports | classnames | | autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:13:57:13:67 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:13:70:13:82 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:14:31:14:77 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:14:31:14:77 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:14:31:14:77 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:14:32:14:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:14:32:14:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:14:32:14:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:14:47:14:62 | safeStyle('foo') | stringConcatenatedWith | 'Hello' | @@ -9868,30 +12294,30 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | calleeImports | classnames | | autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:14:57:14:61 | 'foo' | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:14:64:14:76 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:15:31:15:78 | `` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:15:31:15:78 | `` | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:15:31:15:78 | `` | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:15:32:15:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:15:32:15:44 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:15:32:15:44 | Hello' | | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) | stringConcatenatedWith | 'Hello' | @@ -9900,15 +12326,408 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | calleeImports | clsx | | autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:15:52:15:62 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | contextFunctionInterfaces | main() | | autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | | autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | enclosingFunctionName | main | | autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | | autogenerated/Xss/DomBasedXss/classnames.js:15:65:15:77 | ">Hello | stringConcatenatedWith | 'Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:27 | documen ... nerHTML | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:27 | documen ... nerHTML | fileImports | classnames classnames/bind classnames/dedupe clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:27 | documen ... nerHTML | stringConcatenatedWith | -endpoint- 'Hello' | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... ` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... ` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... ` | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... ` | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... ` | fileImports | classnames classnames/bind classnames/dedupe clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:33:17:45 | Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:33:17:45 | Hello' | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | fileImports | classnames classnames/bind classnames/dedupe clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) | stringConcatenatedWith | document.body.innerHTML + 'Hello' | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | CalleeFlexibleAccessPath | clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | calleeImports | clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/classnames.js:17:53:17:63 | window.name | fileImports | classnames classnames/bind classnames/dedupe clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | enclosingFunctionBody | document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello unsafeStyle classNames bind foo window name document body innerHTML Hello safeStyle classNames bind document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello document body innerHTML Hello | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | fileImports | classnames classnames/bind classnames/dedupe clsx | +| autogenerated/Xss/DomBasedXss/classnames.js:17:66:17:78 | ">Hello | stringConcatenatedWith | document.body.innerHTML + ' ... \\n } | CalleeFlexibleAccessPath | el.addEventListener | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | enclosingFunctionBody | el HTMLElement el addEventListener paste e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:23:34:25:5 | (e) => ... \\n } | receiverName | el | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | enclosingFunctionBody | el HTMLElement el addEventListener paste e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:11:24:15 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | enclosingFunctionBody | el HTMLElement el addEventListener paste e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:23:24:58 | e.clipb ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | CalleeFlexibleAccessPath | e.clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | enclosingFunctionBody | el HTMLElement el addEventListener paste e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/clipboard.ts:24:47:24:57 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | CalleeFlexibleAccessPath | document.addEventListener | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:27:28:33 | 'paste' | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | CalleeFlexibleAccessPath | document.addEventListener | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:28:36:30:1 | (e) => ... OT OK\\n} | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | enclosingFunctionBody | e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:7:29:11 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | enclosingFunctionBody | e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:19:29:54 | e.clipb ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | CalleeFlexibleAccessPath | e.clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | enclosingFunctionBody | e $ #id html e clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:29:43:29:53 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:3:32:8 | "#foo" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:3:32:8 | "#foo" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:3:32:8 | "#foo" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:3:32:8 | "#foo" | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:3:32:8 | "#foo" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:16:32:22 | 'paste' | CalleeFlexibleAccessPath | $().bind | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:16:32:22 | 'paste' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:16:32:22 | 'paste' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:16:32:22 | 'paste' | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:16:32:22 | 'paste' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:25:34:1 | (e) => ... OT OK\\n} | CalleeFlexibleAccessPath | $().bind | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:25:34:1 | (e) => ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:25:34:1 | (e) => ... OT OK\\n} | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:25:34:1 | (e) => ... OT OK\\n} | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:32:25:34:1 | (e) => ... OT OK\\n} | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | enclosingFunctionBody | e $ #id html e originalEvent clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:7:33:11 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | enclosingFunctionBody | e $ #id html e originalEvent clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:19:33:68 | e.origi ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | CalleeFlexibleAccessPath | e.originalEvent.clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | enclosingFunctionBody | e $ #id html e originalEvent clipboardData getData text/html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/clipboard.ts:33:57:33:67 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:37:38:37:42 | "div" | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | CalleeFlexibleAccessPath | clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:42:44:42:55 | 'text/plain' | receiverName | clipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | CalleeFlexibleAccessPath | clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:43:44:43:54 | 'text/html' | receiverName | clipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:48:44:48:48 | 'div' | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:50:29:50:32 | html | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | CalleeFlexibleAccessPath | document.body.append | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | enclosingFunctionBody | div document createElement div div onpaste e ClipboardEvent clipboardData e clipboardData text clipboardData getData text/plain html clipboardData getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:66:22:66:45 | e.clipb ... iles[i] | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:66:22:66:45 | e.clipb ... iles[i] | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:66:22:66:45 | e.clipb ... iles[i] | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:66:22:66:45 | e.clipb ... iles[i] | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:66:22:66:45 | e.clipb ... iles[i] | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | CalleeFlexibleAccessPath | e.clipboardData.types.includes | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:70:40:70:50 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | CalleeFlexibleAccessPath | e.clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:71:51:71:61 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:72:48:72:53 | 'html' | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:73:29:73:39 | droppedHtml | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | CalleeFlexibleAccessPath | container.getElementsByTagName | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:74:51:74:55 | 'img' | receiverName | container | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | CalleeFlexibleAccessPath | dropItems.add | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:77:23:77:25 | src | receiverName | dropItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | CalleeFlexibleAccessPath | e.clipboardData.types.includes | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:79:47:79:58 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | CalleeFlexibleAccessPath | e.clipboardData.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:80:49:80:60 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | CalleeFlexibleAccessPath | ?.test | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:82:32:82:40 | plainText | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | CalleeFlexibleAccessPath | dropItems.add | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:83:23:83:31 | plainText | receiverName | dropItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | CalleeFlexibleAccessPath | Array.from | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | enclosingFunctionBody | e ClipboardEvent Promise Array File dropItems Set File e clipboardData files length 0 i 0 i e clipboardData files length i file e clipboardData files i e clipboardData types includes text/html droppedHtml e clipboardData getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e clipboardData types includes text/plain plainText e clipboardData getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | enclosingFunctionName | getClipboardData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:87:35:87:43 | dropItems | receiverName | Array | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:93:38:93:42 | "div" | receiverName | document | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | CalleeFlexibleAccessPath | div.addEventListener | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:26:94:38 | "beforeinput" | receiverName | div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | CalleeFlexibleAccessPath | div.addEventListener | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:94:41:100:5 | functio ... K\\n } | receiverName | div | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | CalleeFlexibleAccessPath | dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:98:43:98:53 | 'text/html' | receiverName | dataTransfer | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:11:99:15 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | contextFunctionInterfaces | getClipboardData(e)\ninstall(el)\nonpaste(e)\npaste(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | enclosingFunctionBody | div document createElement div div addEventListener beforeinput e InputEvent data inputType isComposing dataTransfer e dataTransfer html dataTransfer getData text/html $ #id html html | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/clipboard.ts:99:23:99:26 | html | fileImports | | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | contextFunctionInterfaces | constructor(args)\ntest() | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | enclosingFunctionBody | innerHTML window name | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/custom-element.js:5:26:5:36 | window.name | fileImports | dummy | | autogenerated/Xss/DomBasedXss/d3.js:1:20:1:23 | 'd3' | CalleeFlexibleAccessPath | require | | autogenerated/Xss/DomBasedXss/d3.js:1:20:1:23 | 'd3' | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/d3.js:1:20:1:23 | 'd3' | calleeImports | | @@ -10013,194 +12832,834 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/d3.js:21:15:21:24 | getTaint() | fileImports | d3 | | autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | CalleeFlexibleAccessPath | decodeURIComponent | | autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:9:36:9:68 | window. ... ring(1) | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | CalleeFlexibleAccessPath | window.location.hash.substring | | autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:9:67:9:67 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:11:31:11:70 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | CalleeFlexibleAccessPath | dateFns.format | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | calleeImports | date-fns | -| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:11:57:11:60 | time | receiverName | dateFns | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | CalleeFlexibleAccessPath | dateFns.format | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | calleeImports | date-fns | -| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:11:63:11:67 | taint | receiverName | dateFns | | autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:12:31:12:73 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | CalleeFlexibleAccessPath | dateFnsEsm.format | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | calleeImports | date-fns/esm | -| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:12:60:12:63 | time | receiverName | dateFnsEsm | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | CalleeFlexibleAccessPath | dateFnsEsm.format | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | calleeImports | date-fns/esm | -| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:12:66:12:70 | taint | receiverName | dateFnsEsm | | autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:13:31:13:72 | `Time i ... time)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | CalleeFlexibleAccessPath | dateFnsFp.format | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | calleeImports | date-fns/fp | -| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:13:59:13:63 | taint | receiverName | dateFnsFp | | autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | CalleeFlexibleAccessPath | dateFnsFp.format() | | autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | calleeImports | date-fns/fp | -| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:13:66:13:69 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:14:31:14:70 | `Time i ... time)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | CalleeFlexibleAccessPath | dateFns.format | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | calleeImports | date-fns | -| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:14:57:14:61 | taint | receiverName | dateFns | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | CalleeFlexibleAccessPath | dateFns.format | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | calleeImports | date-fns | -| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:14:64:14:67 | time | receiverName | dateFns | | autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:15:31:15:72 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | CalleeFlexibleAccessPath | dateFnsFp.format | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | calleeImports | date-fns/fp | -| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:15:59:15:62 | time | receiverName | dateFnsFp | | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | CalleeFlexibleAccessPath | dateFnsFp.format() | | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | calleeImports | date-fns/fp | -| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:16:31:16:69 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | CalleeFlexibleAccessPath | moment | | autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | calleeImports | moment | -| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:16:49:16:52 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | CalleeFlexibleAccessPath | moment().format | | autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | calleeImports | moment | -| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:16:62:16:66 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:17:31:17:65 | `Time i ... mat()}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | CalleeFlexibleAccessPath | moment | | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | calleeImports | moment | -| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | assignedToPropName | innerHTML | -| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:18:31:18:66 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | CalleeFlexibleAccessPath | dateformat | | autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | calleeImports | dateformat | -| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:18:53:18:56 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | | autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | CalleeFlexibleAccessPath | dateformat | | autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | calleeImports | dateformat | -| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | contextFunctionInterfaces | main() | +| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | | autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint | +| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | | autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | enclosingFunctionName | main | -| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | fileImports | date-fns date-fns/esm date-fns/fp dateformat moment | +| autogenerated/Xss/DomBasedXss/dates.js:18:59:18:63 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/dates.js:21:31:21:68 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | CalleeFlexibleAccessPath | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | calleeImports | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/dates.js:21:48:21:51 | time | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | CalleeFlexibleAccessPath | dayjs().format | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | calleeImports | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | enclosingFunctionBody | time Date taint decodeURIComponent window location hash substring 1 document body innerHTML Time is dateFns format time taint document body innerHTML Time is dateFnsEsm format time taint document body innerHTML Time is dateFnsFp format taint time document body innerHTML Time is dateFns format taint time document body innerHTML Time is dateFnsFp format time taint document body innerHTML Time is moment time format taint document body innerHTML Time is moment taint format document body innerHTML Time is dateformat time taint dayjs dayjs document body innerHTML Time is dayjs time format taint | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | enclosingFunctionName | main | +| autogenerated/Xss/DomBasedXss/dates.js:21:61:21:65 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | CalleeFlexibleAccessPath | decodeURIComponent | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:30:36:30:68 | window. ... ring(1) | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | CalleeFlexibleAccessPath | window.location.hash.substring | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:30:67:30:67 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:37:31:37:84 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | CalleeFlexibleAccessPath | dateFns.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | calleeImports | @date-io/date-fns | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:37:65:37:74 | new Date() | receiverName | dateFns | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | CalleeFlexibleAccessPath | dateFns.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | calleeImports | @date-io/date-fns | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:37:77:37:81 | taint | receiverName | dateFns | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:38:31:38:84 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | CalleeFlexibleAccessPath | luxon.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | calleeImports | @date-io/luxon | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:38:63:38:74 | luxon.date() | receiverName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | CalleeFlexibleAccessPath | luxon.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | calleeImports | @date-io/luxon | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:38:77:38:81 | taint | receiverName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:39:31:39:86 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | CalleeFlexibleAccessPath | moment.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:64:39:76 | moment.date() | receiverName | moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | CalleeFlexibleAccessPath | moment.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:39:79:39:83 | taint | receiverName | moment | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:40:31:40:84 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | CalleeFlexibleAccessPath | dayjs.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | calleeImports | @date-io/dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:40:63:40:74 | dayjs.date() | receiverName | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | CalleeFlexibleAccessPath | dayjs.formatByString | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | calleeImports | @date-io/dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 dateFns DateFnsAdapter luxon LuxonAdapter moment MomentAdapter dayjs DayJSAdapter document body innerHTML Time is dateFns formatByString Date taint document body innerHTML Time is luxon formatByString luxon date taint document body innerHTML Time is moment formatByString moment date taint document body innerHTML Time is dayjs formatByString dayjs date taint | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | enclosingFunctionName | dateio | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:40:77:40:81 | taint | receiverName | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | CalleeFlexibleAccessPath | decodeURIComponent | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:46:36:46:68 | window. ... ring(1) | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | CalleeFlexibleAccessPath | window.location.hash.substring | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:46:67:46:67 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:31:48:90 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | CalleeFlexibleAccessPath | DateTime.now().plus | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:62:48:71 | {years: 1} | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | CalleeFlexibleAccessPath | DateTime.now().plus | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | InputAccessPathFromCallee | 0.years | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | assignedToPropName | years | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:70:48:70 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | CalleeFlexibleAccessPath | DateTime.now().plus().toFormat | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:48:83:48:87 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:49:31:49:89 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | CalleeFlexibleAccessPath | DateTime().setLocale | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:49:67:49:70 | 'fr' | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | CalleeFlexibleAccessPath | DateTime().setLocale().toFormat | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:49:82:49:86 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:31:50:104 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | CalleeFlexibleAccessPath | DateTime.fromISO | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:50:59:50:70 | "2020-01-01" | receiverName | DateTime | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | CalleeFlexibleAccessPath | DateTime.fromISO().startOf | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:81:50:85 | 'day' | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | CalleeFlexibleAccessPath | DateTime.fromISO().startOf().toFormat | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | calleeImports | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 document body innerHTML Time is DateTime now plus years 1 toFormat taint document body innerHTML Time is DateTime setLocale fr toFormat taint document body innerHTML Time is DateTime fromISO 2020-01-01 startOf day toFormat taint | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | enclosingFunctionName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:50:97:50:101 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | CalleeFlexibleAccessPath | decodeURIComponent | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:54:36:54:68 | window. ... ring(1) | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | CalleeFlexibleAccessPath | window.location.hash.substring | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:54:67:54:67 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:57:31:57:101 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | CalleeFlexibleAccessPath | moment.addDays | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:57:57:81 | moment. ... 06-21") | receiverName | moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | CalleeFlexibleAccessPath | moment.date | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:69:57:80 | "2020-06-21" | receiverName | moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | CalleeFlexibleAccessPath | moment.addDays | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:84:57:84 | 1 | receiverName | moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | CalleeFlexibleAccessPath | moment.addDays().format | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | calleeImports | @date-io/moment | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:57:94:57:98 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:59:31:59:87 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | CalleeFlexibleAccessPath | luxon.endOfDay | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | calleeImports | @date-io/luxon | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:59:57:59:68 | luxon.date() | receiverName | luxon | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | CalleeFlexibleAccessPath | luxon.endOfDay().toFormat | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | calleeImports | @date-io/luxon | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:59:80:59:84 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:61:31:61:88 | `Time i ... aint)}` | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | CalleeFlexibleAccessPath | dayjs.setHours | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | calleeImports | @date-io/dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:61:57:61:68 | dayjs.date() | receiverName | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | CalleeFlexibleAccessPath | dayjs.setHours | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | calleeImports | @date-io/dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dates.js:61:71:61:71 | 4 | receiverName | dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | CalleeFlexibleAccessPath | dayjs.setHours().format | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | calleeImports | @date-io/dayjs | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | contextFunctionInterfaces | dateio()\ndateio2()\nluxon()\nmain() | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | enclosingFunctionBody | taint decodeURIComponent window location hash substring 1 moment MomentAdapter document body innerHTML Time is moment addDays moment date 2020-06-21 1 format taint luxon LuxonAdapter document body innerHTML Time is luxon endOfDay luxon date toFormat taint dayjs DayJSAdapter document body innerHTML Time is dayjs setHours dayjs date 4 format taint | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | enclosingFunctionName | dateio2 | +| autogenerated/Xss/DomBasedXss/dates.js:61:81:61:85 | taint | fileImports | @date-io/date-fns @date-io/dayjs @date-io/luxon @date-io/moment date-fns date-fns/esm date-fns/fp dateformat dayjs luxon moment | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:3:1:8 | "#foo" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:3:1:8 | "#foo" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:3:1:8 | "#foo" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:3:1:8 | "#foo" | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:3:1:8 | "#foo" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:14:1:19 | "drop" | CalleeFlexibleAccessPath | $().on | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:14:1:19 | "drop" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:14:1:19 | "drop" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:14:1:19 | "drop" | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:14:1:19 | "drop" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:22:1:25 | drop | CalleeFlexibleAccessPath | $().on | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:22:1:25 | drop | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:22:1:25 | drop | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:22:1:25 | drop | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:1:22:1:25 | drop | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | CalleeFlexibleAccessPath | dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:7:39:7:50 | 'text/plain' | receiverName | dataTransfer | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | CalleeFlexibleAccessPath | dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:39:8:49 | 'text/html' | receiverName | dataTransfer | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:13:40:13:44 | 'div' | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:15:25:15:28 | html | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | CalleeFlexibleAccessPath | document.body.append | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | enclosingFunctionBody | e dataTransfer e originalEvent dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | enclosingFunctionName | drop | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | CalleeFlexibleAccessPath | el.addEventListener | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | contextSurroundingFunctionParameters | (el) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | enclosingFunctionBody | el HTMLElement el addEventListener drop e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:25:23:30 | 'drop' | receiverName | el | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | CalleeFlexibleAccessPath | el.addEventListener | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | enclosingFunctionBody | el HTMLElement el addEventListener drop e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:23:33:25:5 | (e) => ... \\n } | receiverName | el | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | enclosingFunctionBody | el HTMLElement el addEventListener drop e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:11:24:15 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | enclosingFunctionBody | el HTMLElement el addEventListener drop e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:23:24:57 | e.dataT ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | CalleeFlexibleAccessPath | e.dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | contextSurroundingFunctionParameters | (el)\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | enclosingFunctionBody | el HTMLElement el addEventListener drop e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | enclosingFunctionName | install | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:24:46:24:56 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | CalleeFlexibleAccessPath | document.addEventListener | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:27:28:32 | 'drop' | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | CalleeFlexibleAccessPath | document.addEventListener | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:28:35:30:1 | (e) => ... OT OK\\n} | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | enclosingFunctionBody | e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:7:29:11 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | enclosingFunctionBody | e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:19:29:53 | e.dataT ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | CalleeFlexibleAccessPath | e.dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | enclosingFunctionBody | e $ #id html e dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | enclosingFunctionName | document.addEventListener#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:29:42:29:52 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:3:32:8 | "#foo" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:3:32:8 | "#foo" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:3:32:8 | "#foo" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:3:32:8 | "#foo" | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:3:32:8 | "#foo" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:16:32:21 | 'drop' | CalleeFlexibleAccessPath | $().bind | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:16:32:21 | 'drop' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:16:32:21 | 'drop' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:16:32:21 | 'drop' | contextSurroundingFunctionParameters | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:16:32:21 | 'drop' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:24:34:1 | (e) => ... OT OK\\n} | CalleeFlexibleAccessPath | $().bind | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:24:34:1 | (e) => ... OT OK\\n} | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:24:34:1 | (e) => ... OT OK\\n} | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:24:34:1 | (e) => ... OT OK\\n} | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:32:24:34:1 | (e) => ... OT OK\\n} | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | enclosingFunctionBody | e $ #id html e originalEvent dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:7:33:11 | "#id" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | CalleeFlexibleAccessPath | $().html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | enclosingFunctionBody | e $ #id html e originalEvent dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:19:33:67 | e.origi ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | CalleeFlexibleAccessPath | e.originalEvent.dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | enclosingFunctionBody | e $ #id html e originalEvent dataTransfer getData text/html | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | enclosingFunctionName | bind#functionalargument | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:33:56:33:66 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:37:38:37:42 | "div" | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | CalleeFlexibleAccessPath | dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:42:43:42:54 | 'text/plain' | receiverName | dataTransfer | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | CalleeFlexibleAccessPath | dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:43:43:53 | 'text/html' | receiverName | dataTransfer | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:48:44:48:48 | 'div' | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:50:29:50:32 | html | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | CalleeFlexibleAccessPath | document.body.append | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | contextSurroundingFunctionParameters | ()\n(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | enclosingFunctionBody | div document createElement div div ondrop e DragEvent dataTransfer e dataTransfer text dataTransfer getData text/plain html dataTransfer getData text/html text html e preventDefault div document createElement div html div innerHTML html div textContent text document body append div | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:66:22:66:44 | e.dataT ... iles[i] | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:66:22:66:44 | e.dataT ... iles[i] | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:66:22:66:44 | e.dataT ... iles[i] | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:66:22:66:44 | e.dataT ... iles[i] | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:66:22:66:44 | e.dataT ... iles[i] | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | CalleeFlexibleAccessPath | e.dataTransfer.types.includes | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:70:39:70:49 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | CalleeFlexibleAccessPath | e.dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:71:50:71:60 | 'text/html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | CalleeFlexibleAccessPath | document.createElement | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:72:48:72:53 | 'html' | receiverName | document | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | assignedToPropName | innerHTML | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:73:29:73:39 | droppedHtml | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | CalleeFlexibleAccessPath | container.getElementsByTagName | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:74:51:74:55 | 'img' | receiverName | container | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | CalleeFlexibleAccessPath | dropItems.add | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:77:23:77:25 | src | receiverName | dropItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | CalleeFlexibleAccessPath | e.dataTransfer.types.includes | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:79:46:79:57 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | CalleeFlexibleAccessPath | e.dataTransfer.getData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:80:48:80:59 | 'text/plain' | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | CalleeFlexibleAccessPath | ?.test | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:82:32:82:40 | plainText | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | CalleeFlexibleAccessPath | dropItems.add | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:83:23:83:31 | plainText | receiverName | dropItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | CalleeFlexibleAccessPath | Array.from | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | contextFunctionInterfaces | drop(e)\ngetDropData(e)\ninstall(el)\nondrop(e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | contextSurroundingFunctionParameters | (e) | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | enclosingFunctionBody | e DragEvent Promise Array File dropItems Set File e dataTransfer files length 0 i 0 i e dataTransfer files length i file e dataTransfer files i e dataTransfer types includes text/html droppedHtml e dataTransfer getData text/html container document createElement html container innerHTML droppedHtml imgs container getElementsByTagName img imgs length 1 src imgs 0 0 src dropItems add src e dataTransfer types includes text/plain plainText e dataTransfer getData text/plain /^https?:\\/\\//i test plainText dropItems add plainText imageItems Array from dropItems imageItems | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | enclosingFunctionName | getDropData | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | fileImports | | +| autogenerated/Xss/DomBasedXss/dragAndDrop.ts:87:35:87:43 | dropItems | receiverName | Array | | autogenerated/Xss/DomBasedXss/encodeuri.js:3:5:3:15 | 'click | @@ -10319,33 +13778,33 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:4:5:4:11 | tainted | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | CalleeFlexibleAccessPath | $ | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:5:5:5:10 | "body" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | CalleeFlexibleAccessPath | $ | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | InputArgumentIndex | 1 | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:5:13:5:19 | tainted | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | CalleeFlexibleAccessPath | $ | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:6:5:6:17 | "." + tainted | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:16 | "
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:16 | "
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:16 | "
    ' | @@ -10353,18 +13812,18 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:7:5:7:34 | "
    " | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted | stringConcatenatedWith | '
    ' | | autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:7:30:7:34 | "\\">" | stringConcatenatedWith | '
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:8:5:8:10 | "body" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:8:5:8:10 | "body" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:8:5:8:10 | "body" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | CalleeFlexibleAccessPath | $().html | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:8:18:8:34 | "XSS: " + tainted | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | CalleeFlexibleAccessPath | $ | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:9:5:9:24 | window.location.hash | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:9 | "" | stringConcatenatedWith | -endpoint- location.toString() + '' | @@ -10399,18 +13858,18 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:10:5:10:40 | "" + ... "" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() | stringConcatenatedWith | '' -endpoint- '' | | autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:10:35:10:40 | "" | stringConcatenatedWith | '' + location.toString() -endpoint- | @@ -10418,49 +13877,276 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:13:37:13:39 | 'x' | receiverName | document | | autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:14:19:14:58 | decodeU ... n.hash) | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | CalleeFlexibleAccessPath | decodeURIComponent | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:14:38:14:57 | window.location.hash | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:15:19:15:60 | decodeU ... search) | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | CalleeFlexibleAccessPath | decodeURIComponent | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:15:38:15:59 | window. ... .search | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | assignedToPropName | innerHTML | | autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:16:19:16:64 | decodeU ... ring()) | fileImports | | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | CalleeFlexibleAccessPath | decodeURIComponent | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | contextFunctionInterfaces | test() | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | contextSurroundingFunctionParameters | () | -| autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString | +| autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | enclosingFunctionName | test | | autogenerated/Xss/DomBasedXss/jquery.js:16:38:16:63 | window. ... tring() | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:19:5:19:8 | hash | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:21:5:21:21 | hash.substring(1) | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | CalleeFlexibleAccessPath | hash.substring | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:21:20:21:20 | 1 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:22:5:22:25 | hash.su ... (1, 10) | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | CalleeFlexibleAccessPath | hash.substring | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:22:20:22:20 | 1 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | CalleeFlexibleAccessPath | hash.substring | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:22:23:22:24 | 10 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:23:5:23:18 | hash.substr(1) | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | CalleeFlexibleAccessPath | hash.substr | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:23:17:23:17 | 1 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:24:5:24:17 | hash.slice(1) | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | CalleeFlexibleAccessPath | hash.slice | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:24:16:24:16 | 1 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:25:5:25:25 | hash.su ... (0, 10) | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | CalleeFlexibleAccessPath | hash.substring | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:25:20:25:20 | 0 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | CalleeFlexibleAccessPath | hash.substring | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:25:23:25:24 | 10 | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:27:5:27:25 | hash.re ... #', '') | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:27:18:27:20 | '#' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:27:23:27:24 | '' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:28:5:28:43 | window. ... ?', '') | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | CalleeFlexibleAccessPath | window.location.search.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:28:36:28:38 | '?' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | CalleeFlexibleAccessPath | window.location.search.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:28:41:28:42 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:29:5:29:25 | hash.re ... !', '') | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:29:18:29:20 | '!' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:29:23:29:24 | '' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:30:5:30:28 | hash.re ... h', '') | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:30:18:30:23 | 'blah' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | CalleeFlexibleAccessPath | hash.replace | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:30:26:30:27 | '' | receiverName | hash | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:32:5:32:17 | hash + 'blah' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:33:5:33:17 | 'blah' + hash | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:9 | '' | stringConcatenatedWith | -endpoint- hash + '' | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | CalleeFlexibleAccessPath | $ | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:34:5:34:25 | '' + ... '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash | stringConcatenatedWith | '' -endpoint- '' | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | contextFunctionInterfaces | test() | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | enclosingFunctionBody | tainted document location search $ tainted $ body tainted $ . tainted $
    $ body html XSS: tainted $ window location hash $ location toString elm document getElementById x elm innerHTML decodeURIComponent window location hash elm innerHTML decodeURIComponent window location search elm innerHTML decodeURIComponent window location toString hash window location hash $ hash $ hash substring 1 $ hash substring 1 10 $ hash substr 1 $ hash slice 1 $ hash substring 0 10 $ hash replace # $ window location search replace ? $ hash replace ! $ hash replace blah $ hash blah $ blah hash $ hash | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | enclosingFunctionName | test | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | fileImports | | +| autogenerated/Xss/DomBasedXss/jquery.js:34:20:34:25 | '' | stringConcatenatedWith | '' + hash -endpoint- | | autogenerated/Xss/DomBasedXss/jwt-server.js:1:23:1:31 | 'express' | CalleeFlexibleAccessPath | require | | autogenerated/Xss/DomBasedXss/jwt-server.js:1:23:1:31 | 'express' | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/jwt-server.js:1:23:1:31 | 'express' | calleeImports | | @@ -11957,6 +15643,105 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/translate.js:11:56:11:61 | 'term' | enclosingFunctionName | | | autogenerated/Xss/DomBasedXss/translate.js:11:56:11:61 | 'term' | fileImports | | | autogenerated/Xss/DomBasedXss/translate.js:11:56:11:61 | 'term' | receiverName | searchParams | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:47:2:49 | 'x' | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:52:2:73 | { creat ... => x } | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | InputAccessPathFromCallee | 1.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | assignedToPropName | createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | contextSurroundingFunctionParameters | ()\n(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:2:66:2:71 | x => x | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | CalleeFlexibleAccessPath | policy1.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:3:24:3:34 | window.name | receiverName | policy1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:47:5:49 | 'x' | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:52:5:78 | { creat ... safe' } | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | InputAccessPathFromCallee | 1.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | assignedToPropName | createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | contextSurroundingFunctionParameters | ()\n(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:5:66:5:76 | x => 'safe' | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | CalleeFlexibleAccessPath | policy2.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:6:24:6:34 | window.name | receiverName | policy2 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:47:8:49 | 'x' | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:52:8:73 | { creat ... => x } | receiverName | trustedTypes | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | CalleeFlexibleAccessPath | trustedTypes.createPolicy | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | InputAccessPathFromCallee | 1.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | InputArgumentIndex | 1 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | assignedToPropName | createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | contextSurroundingFunctionParameters | ()\n(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:8:66:8:71 | x => x | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | CalleeFlexibleAccessPath | policy3.createHTML | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | InputArgumentIndex | 0 | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | contextFunctionInterfaces | createHTML(x)\ncreateHTML(x)\ncreateHTML(x) | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | contextSurroundingFunctionParameters | () | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | enclosingFunctionBody | policy1 trustedTypes createPolicy x createHTML x x policy1 createHTML window name policy2 trustedTypes createPolicy x createHTML x safe policy2 createHTML window name policy3 trustedTypes createPolicy x createHTML x x policy3 createHTML safe | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | enclosingFunctionName | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | fileImports | | +| autogenerated/Xss/DomBasedXss/trusted-types.js:9:24:9:29 | 'safe' | receiverName | policy3 | | autogenerated/Xss/DomBasedXss/tst3.js:1:35:1:39 | "foo" | CalleeFlexibleAccessPath | document.getElementById | | autogenerated/Xss/DomBasedXss/tst3.js:1:35:1:39 | "foo" | InputArgumentIndex | 0 | | autogenerated/Xss/DomBasedXss/tst3.js:1:35:1:39 | "foo" | contextFunctionInterfaces | | @@ -12095,1751 +15880,2210 @@ tokenFeatures | autogenerated/Xss/DomBasedXss/tst3.js:15:23:15:29 | data[p] | receiverName | foo | | autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | CalleeFlexibleAccessPath | $ | | autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | fileImports | | +| autogenerated/Xss/DomBasedXss/tst.js:5:5:5:10 | 'myId' | fileImports | ansi-to-html | | autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | CalleeFlexibleAccessPath | $().html | | autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:5:18:5:23 | target | fileImports | | -| autogenerated/Xss/DomBasedXss/tst.js:8:18:8:35 | " document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:35 | "' | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | CalleeFlexibleAccessPath | document.write | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | fileImports | | +| autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | fileImports | ansi-to-html | | autogenerated/Xss/DomBasedXss/tst.js:8:18:8:126 | "" | receiverName | document | -| autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | fileImports | | +| autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | fileImports | ansi-to-html | | autogenerated/Xss/DomBasedXss/tst.js:8:37:8:114 | documen ... t=")+8) | stringConcatenatedWith | '' | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | CalleeFlexibleAccessPath | document.location.href.substring | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | fileImports | | +| autogenerated/Xss/DomBasedXss/tst.js:8:70:8:113 | documen ... lt=")+8 | fileImports | ansi-to-html | | autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | CalleeFlexibleAccessPath | document.location.href.indexOf | | autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | InputArgumentIndex | 0 | -| autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | fileImports | | -| autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nwindowName()\nwindowNameAssigned()\nwrap(s) | +| autogenerated/Xss/DomBasedXss/tst.js:8:101:8:110 | "default=" | fileImports | ansi-to-html | +| autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | contextFunctionInterfaces | URLPseudoProperties()\nangularJSServices()\nansiToHTML()\nbar()\nbasicExceptions()\nbaz(x)\nchop(s)\nconstructor()\nconstructor(args)\nconstructor(props)\ndangerouslySetInnerHtml(s)\ndomMethods()\nflowThroughPropertyNames()\nfoo(target)\ngetTaintedUrl()\ngetUrl()\ngrowl()\nhandlebarsSafeString()\nhash()\nhash2()\njqueryLocation()\nlink(scope, element)\nmootools()\nmyPlugin()\nnonGlobalSanitizer()\nreact()\nreferences()\nrender()\ntest()\ntest()\ntest()\ntest()\ntest()\ntest2()\ntestCreateContextualFragment()\ntestDOMParser()\nthisNodes()\ntst()\nurlStuff()\nwindowName()\nwindowNameAssigned()\nwrap(s) | | autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | contextSurroundingFunctionParameters | () | | autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | enclosingFunctionBody | target document location search $ myId html target document write document write $
    $
    $
    params URL document location searchParams $ name html params get name searchParams URLSearchParams target substring 1 $ name html searchParams get name | | autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | enclosingFunctionName | test | -| autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | fileImports | | +| autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | fileImports | ansi-to-html | | autogenerated/Xss/DomBasedXss/tst.js:8:116:8:126 | "" | stringConcatenatedWith | '